Fix on_quote_combo_change callback
[pspp] / src / language / data-io / data-parser.c
index 63f9f0eda64afd0cf228a8bb4c43010870f15dc2..2f24b8a23886877be6dbde22f680b209b9d4108f 100644 (file)
 #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 ("%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 +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);
 }