X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Foutput%2Fcsv.c;h=ba1481c9a0c44caf9ab2de9873b67aa2f49dd604;hb=refs%2Fheads%2Fctables7;hp=6ff61382d2519de749e5f2b98e0eea3eefba3846;hpb=28e907dd4809de2c44feb9f402ab7f19660d6459;p=pspp diff --git a/src/output/csv.c b/src/output/csv.c index 6ff61382d2..ba1481c9a0 100644 --- a/src/output/csv.c +++ b/src/output/csv.c @@ -26,12 +26,11 @@ #include "libpspp/message.h" #include "libpspp/str.h" #include "libpspp/string-map.h" -#include "output/text-item.h" #include "output/driver-provider.h" #include "output/options.h" -#include "output/message-item.h" -#include "output/page-eject-item.h" -#include "output/table-item.h" +#include "output/output-item.h" +#include "output/pivot-output.h" +#include "output/pivot-table.h" #include "output/table-provider.h" #include "gl/minmax.h" @@ -78,10 +77,9 @@ csv_create (struct file_handle *fh, enum settings_output_devices device_type, struct string_map *o) { struct output_driver *d; - struct csv_driver *csv; char *quote; - csv = xzalloc (sizeof *csv); + struct csv_driver *csv = XZALLOC (struct csv_driver); d = &csv->driver; output_driver_init (&csv->driver, &csv_driver_class, fh_get_file_name (fh), device_type); @@ -175,141 +173,115 @@ csv_output_lines (struct csv_driver *csv, const char *text_) } static void -csv_format_footnotes (struct footnote **f, size_t n, struct string *s) +csv_output_table_cell (struct csv_driver *csv, const struct pivot_table *pt, + const struct table_cell *cell, const char *leader) { - for (size_t i = 0; i < n; i++) - ds_put_format (s, "[%s]", f[i]->marker); -} - -static void -csv_output_table_item_text (struct csv_driver *csv, - const struct table_item_text *text, - const char *leader) -{ - if (!text) - return; - struct string s = DS_EMPTY_INITIALIZER; - ds_put_format (&s, "%s: %s", leader, text->content); - csv_format_footnotes (text->footnotes, text->n_footnotes, &s); + if (leader) + ds_put_format (&s, "%s: ", leader); + pivot_value_format (cell->value, pt, &s); csv_output_field (csv, ds_cstr (&s)); ds_destroy (&s); - putc ('\n', csv->file); } static void -csv_submit (struct output_driver *driver, - const struct output_item *output_item) +csv_output_table__ (struct csv_driver *csv, const struct pivot_table *pt, + const struct table *t, const char *leader) { - struct csv_driver *csv = csv_driver_cast (driver); + if (!t) + return; - if (is_table_item (output_item)) + for (int y = 0; y < t->n[TABLE_VERT]; y++) { - struct table_item *table_item = to_table_item (output_item); - const struct table *t = table_item_get_table (table_item); - int x, y; + for (int x = 0; x < t->n[TABLE_HORZ]; x++) + { + struct table_cell cell; - csv_put_separator (csv); + table_get_cell (t, x, y, &cell); - if (csv->titles) - csv_output_table_item_text (csv, table_item_get_title (table_item), - "Table"); + if (x > 0) + fputs (csv->separator, csv->file); - for (y = 0; y < t->n[TABLE_VERT]; y++) - { - for (x = 0; x < t->n[TABLE_HORZ]; x++) - { - struct table_cell cell; - - table_get_cell (t, x, y, &cell); - - if (x > 0) - fputs (csv->separator, csv->file); - - if (x != cell.d[TABLE_HORZ][0] || y != cell.d[TABLE_VERT][0]) - csv_output_field (csv, ""); - else if (!(cell.options & TAB_MARKUP) && !cell.n_footnotes - && !cell.n_subscripts) - csv_output_field (csv, cell.text); - else - { - struct string s = DS_EMPTY_INITIALIZER; - - if (cell.options & TAB_MARKUP) - { - char *t = output_get_text_from_markup (cell.text); - ds_put_cstr (&s, t); - free (t); - } - else - ds_put_cstr (&s, cell.text); - - if (cell.n_subscripts) - for (size_t i = 0; i < cell.n_subscripts; i++) - ds_put_format (&s, "%c%s", - i ? ',' : '_', cell.subscripts[i]); - csv_format_footnotes (cell.footnotes, cell.n_footnotes, &s); - csv_output_field (csv, ds_cstr (&s)); - ds_destroy (&s); - } - } - putc ('\n', csv->file); + if (x != cell.d[TABLE_HORZ][0] || y != cell.d[TABLE_VERT][0]) + csv_output_field (csv, ""); + else + csv_output_table_cell (csv, pt, &cell, !x ? leader : NULL); } + putc ('\n', csv->file); + } +} - if (csv->captions) - csv_output_table_item_text (csv, table_item_get_caption (table_item), - "Caption"); - - struct footnote **f; - size_t n_footnotes = table_collect_footnotes (table_item, &f); - if (n_footnotes) - { - fputs ("\nFootnotes:\n", csv->file); +static void +csv_output_table_layer (struct csv_driver *csv, const struct pivot_table *pt, + const size_t *layer_indexes) +{ + struct table *title, *layers, *body, *caption, *footnotes; + pivot_output (pt, layer_indexes, true, &title, &layers, &body, + &caption, &footnotes, NULL, NULL); + + csv_put_separator (csv); + csv_output_table__ (csv, pt, title, "Table"); + csv_output_table__ (csv, pt, layers, "Layer"); + csv_output_table__ (csv, pt, body, NULL); + csv_output_table__ (csv, pt, caption, "Caption"); + csv_output_table__ (csv, pt, footnotes, "Footnote"); + + table_unref (title); + table_unref (layers); + table_unref (body); + table_unref (caption); + table_unref (footnotes); +} - for (size_t i = 0; i < n_footnotes; i++) - { - csv_output_field (csv, f[i]->marker); - fputs (csv->separator, csv->file); - csv_output_field (csv, f[i]->content); - putc ('\n', csv->file); - } +static void +csv_submit (struct output_driver *driver, + const struct output_item *item) +{ + struct csv_driver *csv = csv_driver_cast (driver); - free (f); - } - } - else if (is_text_item (output_item)) + switch (item->type) { - const struct text_item *text_item = to_text_item (output_item); - enum text_item_type type = text_item_get_type (text_item); - const char *text = text_item_get_text (text_item); + case OUTPUT_ITEM_CHART: + break; - if (type == TEXT_ITEM_SYNTAX || type == TEXT_ITEM_PAGE_TITLE) - return; + case OUTPUT_ITEM_GROUP: + break; - csv_put_separator (csv); + case OUTPUT_ITEM_IMAGE: + break; - if (text_item->markup) - { - char *plain_text = output_get_text_from_markup (text); - csv_output_lines (csv, plain_text); - free (plain_text); - } - else - csv_output_lines (csv, text); - } - else if (is_page_eject_item (output_item)) - { - csv_put_separator (csv); - csv_output_lines (csv, ""); - } - else if (is_message_item (output_item)) - { - const struct message_item *message_item = to_message_item (output_item); - char *s = msg_to_string (message_item_get_msg (message_item)); + case OUTPUT_ITEM_MESSAGE: csv_put_separator (csv); + char *s = msg_to_string (item->message); csv_output_field (csv, s); free (s); putc ('\n', csv->file); + break; + + case OUTPUT_ITEM_PAGE_BREAK: + csv_put_separator (csv); + csv_output_lines (csv, ""); + break; + + case OUTPUT_ITEM_TABLE: + { + size_t *layer_indexes; + PIVOT_OUTPUT_FOR_EACH_LAYER (layer_indexes, item->table, true) + csv_output_table_layer (csv, item->table, layer_indexes); + } + break; + + case OUTPUT_ITEM_TEXT: + if (item->text.subtype == TEXT_ITEM_SYNTAX + || item->text.subtype == TEXT_ITEM_PAGE_TITLE) + return; + + csv_put_separator (csv); + + char *text = text_item_get_plain_text (item); + csv_output_lines (csv, text); + free (text); + break; } } @@ -317,8 +289,8 @@ struct output_driver_factory csv_driver_factory = { "csv", "-", csv_create }; static const struct output_driver_class csv_driver_class = { - "csv", - csv_destroy, - csv_submit, - csv_flush, + .name = "csv", + .destroy = csv_destroy, + .submit = csv_submit, + .flush = csv_flush, };