X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fdata-io%2Fdata-parser.c;h=03c6dbbb0ea36a421a956498f2fb4470c14771a3;hb=b70dcc901c6b6b28a310ffc58aca13daa2a58d67;hp=1d8a493e0db49e54b96f0d1063fd5ab69f6bc95f;hpb=2331dc47df5d45733218e418163f7f5ae99a6324;p=pspp diff --git a/src/language/data-io/data-parser.c b/src/language/data-io/data-parser.c index 1d8a493e0d..03c6dbbb0e 100644 --- a/src/language/data-io/data-parser.c +++ b/src/language/data-io/data-parser.c @@ -31,17 +31,18 @@ #include "language/data-io/data-reader.h" #include "libpspp/message.h" #include "libpspp/str.h" -#include "output/tab.h" +#include "output/pivot-table.h" #include "gl/xalloc.h" #include "gettext.h" +#define N_(msgid) msgid #define _(msgid) gettext (msgid) /* Data parser for textual data like that read by DATA LIST. */ struct data_parser { - const struct dictionary *dict; /*Dictionary of destination */ + struct dictionary *dict; /* Dictionary of destination */ enum data_parser_type type; /* Type of data to parse. */ int skip_records; /* Records to skip before first real data. */ @@ -79,7 +80,7 @@ static void set_any_sep (struct data_parser *parser); /* Creates and returns a new data parser. */ struct data_parser * -data_parser_create (const struct dictionary *dict) +data_parser_create (struct dictionary *dict) { struct data_parser *parser = xmalloc (sizeof *parser); @@ -89,7 +90,7 @@ data_parser_create (const struct dictionary *dict) parser->fields = NULL; parser->field_cnt = 0; parser->field_allocated = 0; - parser->dict = dict; + parser->dict = dict_ref (dict); parser->span = true; parser->empty_line_has_field = false; @@ -114,6 +115,7 @@ data_parser_destroy (struct data_parser *parser) { size_t i; + dict_unref (parser->dict); for (i = 0; i < parser->field_cnt; i++) free (parser->fields[i].name); free (parser->fields); @@ -493,18 +495,24 @@ static void parse_error (const struct dfm_reader *reader, const struct field *field, int first_column, int last_column, char *error) { - struct msg m = { - .category = MSG_C_DATA, - .severity = MSG_S_WARNING, - .file_name = CONST_CAST (char *, dfm_get_file_name (reader)), - .first_line = dfm_get_line_number (reader), - .last_line = m.first_line + 1, + int line_number = dfm_get_line_number (reader); + struct msg_location *location = xmalloc (sizeof *location); + *location = (struct msg_location) { + .file_name = xstrdup (dfm_get_file_name (reader)), + .first_line = line_number, + .last_line = line_number + 1, .first_column = first_column, .last_column = last_column, + }; + struct msg *m = xmalloc (sizeof *m); + *m = (struct msg) { + .category = MSG_C_DATA, + .severity = MSG_S_WARNING, + .location = location, .text = xasprintf (_("Data for variable %s is not valid as format %s: %s"), field->name, fmt_name (field->format.type), error), }; - msg_emit (&m); + msg_emit (m); free (error); } @@ -544,12 +552,14 @@ parse_fixed (const struct data_parser *parser, struct dfm_reader *reader, f->format.w); union value *value = case_data_rw_idx (c, f->case_idx); char *error = data_in (s, input_encoding, f->format.type, + settings_get_fmt_settings (), value, fmt_var_width (&f->format), output_encoding); if (error == NULL) data_in_imply_decimals (s, input_encoding, f->format.type, - f->format.d, value); + f->format.d, settings_get_fmt_settings (), + value); else parse_error (reader, f, f->first_column, f->first_column + f->format.w, error); @@ -596,6 +606,7 @@ parse_delimited_span (const struct data_parser *parser, const char *input_encoding = dfm_reader_get_encoding (reader); error = data_in (s, input_encoding, f->format.type, + settings_get_fmt_settings (), case_data_rw_idx (c, f->case_idx), fmt_var_width (&f->format), output_encoding); if (error != NULL) @@ -641,6 +652,7 @@ parse_delimited_no_span (const struct data_parser *parser, const char *input_encoding = dfm_reader_get_encoding (reader); error = data_in (s, input_encoding, f->format.type, + settings_get_fmt_settings (), case_data_rw_idx (c, f->case_idx), fmt_var_width (&f->format), output_encoding); if (error != NULL) @@ -664,37 +676,48 @@ static void dump_fixed_table (const struct data_parser *parser, const struct file_handle *fh) { - struct tab_table *t; - size_t i; - - t = tab_create (4, parser->field_cnt + 1); - tab_headers (t, 0, 0, 1, 0); - tab_text (t, 0, 0, TAB_CENTER | TAT_TITLE, _("Variable")); - tab_text (t, 1, 0, TAB_CENTER | TAT_TITLE, _("Record")); - tab_text (t, 2, 0, TAB_CENTER | TAT_TITLE, _("Columns")); - tab_text (t, 3, 0, TAB_CENTER | TAT_TITLE, _("Format")); - tab_box (t, TAL_1, TAL_1, TAL_0, TAL_1, 0, 0, 3, parser->field_cnt); - tab_hline (t, TAL_2, 0, 3, 1); - - for (i = 0; i < parser->field_cnt; i++) + /* XXX This should not be preformatted. */ + char *title = xasprintf (ngettext ("Reading %d record from %s.", + "Reading %d records from %s.", + parser->records_per_case), + parser->records_per_case, fh_get_name (fh)); + struct pivot_table *table = pivot_table_create__ ( + pivot_value_new_user_text (title, -1), "Fixed Data Records"); + free (title); + + pivot_dimension_create ( + table, PIVOT_AXIS_COLUMN, N_("Attributes"), + N_("Record"), N_("Columns"), N_("Format")); + + struct pivot_dimension *variables = pivot_dimension_create ( + table, PIVOT_AXIS_ROW, N_("Variable")); + variables->root->show_label = true; + for (size_t i = 0; i < parser->field_cnt; i++) { struct field *f = &parser->fields[i]; - char fmt_string[FMT_STRING_LEN_MAX + 1]; - int row = i + 1; - - tab_text (t, 0, row, TAB_LEFT, f->name); - tab_text_format (t, 1, row, 0, "%d", f->record); - tab_text_format (t, 2, row, 0, "%3d-%3d", - f->first_column, f->first_column + f->format.w - 1); - tab_text (t, 3, row, TAB_LEFT | TAB_FIX, - fmt_to_string (&f->format, fmt_string)); + + /* XXX It would be better to have the actual variable here. */ + int variable_idx = pivot_category_create_leaf ( + variables->root, pivot_value_new_user_text (f->name, -1)); + + pivot_table_put2 (table, 0, variable_idx, + pivot_value_new_integer (f->record)); + + int first_column = f->first_column; + int last_column = f->first_column + f->format.w - 1; + char *columns = xasprintf ("%d-%d", first_column, last_column); + pivot_table_put2 (table, 1, variable_idx, + pivot_value_new_user_text (columns, -1)); + free (columns); + + char str[FMT_STRING_LEN_MAX + 1]; + pivot_table_put2 (table, 2, variable_idx, + pivot_value_new_user_text ( + fmt_to_string (&f->format, str), -1)); + } - tab_title (t, ngettext ("Reading %d record from %s.", - "Reading %d records from %s.", - parser->records_per_case), - parser->records_per_case, fh_get_name (fh)); - tab_submit (t); + pivot_table_submit (table); } /* Displays a table giving information on free-format variable parsing @@ -703,30 +726,32 @@ static void dump_delimited_table (const struct data_parser *parser, const struct file_handle *fh) { - struct tab_table *t; - size_t i; + struct pivot_table *table = pivot_table_create__ ( + pivot_value_new_text_format (N_("Reading free-form data from %s."), + fh_get_name (fh)), + "Free-Form Data Records"); - t = tab_create (2, parser->field_cnt + 1); - tab_headers (t, 0, 0, 1, 0); - tab_text (t, 0, 0, TAB_CENTER | TAT_TITLE, _("Variable")); - tab_text (t, 1, 0, TAB_CENTER | TAT_TITLE, _("Format")); - tab_box (t, TAL_1, TAL_1, TAL_0, TAL_1, 0, 0, 1, parser->field_cnt); - tab_hline (t, TAL_2, 0, 1, 1); + pivot_dimension_create ( + table, PIVOT_AXIS_COLUMN, N_("Attributes"), N_("Format")); - for (i = 0; i < parser->field_cnt; i++) + struct pivot_dimension *variables = pivot_dimension_create ( + table, PIVOT_AXIS_ROW, N_("Variable")); + variables->root->show_label = true; + for (size_t i = 0; i < parser->field_cnt; i++) { struct field *f = &parser->fields[i]; - char str[FMT_STRING_LEN_MAX + 1]; - int row = i + 1; - tab_text (t, 0, row, TAB_LEFT, f->name); - tab_text (t, 1, row, TAB_LEFT | TAB_FIX, - fmt_to_string (&f->format, str)); - } + /* XXX It would be better to have the actual variable here. */ + int variable_idx = pivot_category_create_leaf ( + variables->root, pivot_value_new_user_text (f->name, -1)); - tab_title (t, _("Reading free-form data from %s."), fh_get_name (fh)); + char str[FMT_STRING_LEN_MAX + 1]; + pivot_table_put2 (table, 0, variable_idx, + pivot_value_new_user_text ( + fmt_to_string (&f->format, str), -1)); + } - tab_submit (t); + pivot_table_submit (table); } /* Displays a table giving information on how PARSER will read @@ -802,14 +827,14 @@ data_parser_casereader_read (struct casereader *reader UNUSED, void *r_) } static void -data_parser_casereader_destroy (struct casereader *reader UNUSED, void *r_) +data_parser_casereader_destroy (struct casereader *reader, void *r_) { struct data_parser_casereader *r = r_; if (dfm_reader_error (r->reader)) casereader_force_error (reader); - data_parser_destroy (r->parser); dfm_close_reader (r->reader); caseproto_unref (r->proto); + data_parser_destroy (r->parser); free (r); }