X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fsys-file-writer.c;h=aa539a51364fb6804aa1ddfc2b14d2ee545ebbc3;hb=740e24272ba0cbb056e6c1f172596ef974c97604;hp=3e0d3499c9cd543450929e1b5dbb628552bc6640;hpb=51d8c9b54d65bd0aa3944b8fb9d4460875048e14;p=pspp-builds.git diff --git a/src/data/sys-file-writer.c b/src/data/sys-file-writer.c index 3e0d3499..aa539a51 100644 --- a/src/data/sys-file-writer.c +++ b/src/data/sys-file-writer.c @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -90,7 +91,7 @@ struct sfm_writer 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 *); @@ -111,6 +112,11 @@ static void write_variable_display_parameters (struct sfm_writer *w, 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); @@ -136,7 +142,7 @@ sfm_writer_default_options (void) { struct sfm_write_options opts; opts.create_writeable = true; - opts.compress = get_scompression (); + opts.compress = settings_get_scompression (); opts.version = 3; return opts; } @@ -235,6 +241,10 @@ sfm_open_writer (struct file_handle *fh, struct dictionary *d, 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); @@ -333,7 +343,7 @@ write_header (struct sfm_writer *w, const struct dictionary *d) } 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", @@ -421,7 +431,7 @@ write_variable (struct sfm_writer *w, const struct variable *v) /* 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); @@ -445,14 +455,14 @@ write_variable (struct sfm_writer *w, const struct variable *v) 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); } @@ -520,6 +530,72 @@ write_documents (struct sfm_writer *w, const struct dictionary *d) 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, @@ -751,7 +827,7 @@ close_writer (struct sfm_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,