X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fdata-io%2Fdata-parser.c;h=e14cba7dc20f7898a8ee070a5706d553d6c88683;hb=8a6611e7e3bbba8be61cd35f8701f50d6e255e44;hp=63f9f0eda64afd0cf228a8bb4c43010870f15dc2;hpb=d4ff0e074d703dbeb8af5aa3ac470ddda5ebe301;p=pspp diff --git a/src/language/data-io/data-parser.c b/src/language/data-io/data-parser.c index 63f9f0eda6..e14cba7dc2 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,17 +495,17 @@ static void parse_error (const struct dfm_reader *reader, const struct field *field, int first_column, int last_column, char *error) { - struct msg m; - - m.category = MSG_C_DATA; - m.severity = MSG_S_WARNING; - m.file_name = CONST_CAST (char *, dfm_get_file_name (reader)); - m.first_line = dfm_get_line_number (reader); - m.last_line = m.first_line + 1; - m.first_column = first_column; - m.last_column = last_column; - m.text = xasprintf (_("Data for variable %s is not valid as format %s: %s"), - field->name, fmt_name (field->format.type), 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, + .first_column = first_column, + .last_column = last_column, + .text = xasprintf (_("Data for variable %s is not valid as format %s: %s"), + field->name, fmt_name (field->format.type), error), + }; msg_emit (&m); free (error); @@ -664,37 +666,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 ("%3d-%3d", 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 +716,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 +817,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); }