X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Foutput%2Fcsv.c;h=69f12b16f295ef9790487ce78192d391c7649610;hb=ab6a6170a426bbae24d65f7aedaa0c38913ca44c;hp=17c26a062605f96523b96e9cb17ed5ca893a0f0b;hpb=dbe1d88697fe0b37bc1cc5b0bcbacc2d3f26c1f1;p=pspp diff --git a/src/output/csv.c b/src/output/csv.c index 17c26a0626..69f12b16f2 100644 --- a/src/output/csv.c +++ b/src/output/csv.c @@ -30,6 +30,9 @@ #include "output/driver-provider.h" #include "output/options.h" #include "output/message-item.h" +#include "output/page-eject-item.h" +#include "output/pivot-output.h" +#include "output/pivot-table.h" #include "output/table-item.h" #include "output/table-provider.h" @@ -128,56 +131,116 @@ csv_flush (struct output_driver *driver) } static void -csv_output_field (struct csv_driver *csv, const char *field) +csv_output_field__ (struct csv_driver *csv, struct substring field) { - while (*field == ' ') - field++; + ss_ltrim (&field, ss_cstr (" ")); - if (csv->quote && field[strcspn (field, csv->quote_set)]) + if (csv->quote && ss_cspan (field, ss_cstr (csv->quote_set)) < field.length) { - const char *p; - putc (csv->quote, csv->file); - for (p = field; *p != '\0'; p++) + for (size_t i = 0; i < field.length; i++) { - if (*p == csv->quote) + if (field.string[i] == csv->quote) putc (csv->quote, csv->file); - putc (*p, csv->file); + putc (field.string[i], csv->file); } putc (csv->quote, csv->file); } else - fputs (field, csv->file); + fwrite (field.string, field.length, 1, csv->file); } static void -csv_format_footnotes (const struct footnote **f, size_t n, struct string *s) +csv_output_field (struct csv_driver *csv, const char *field) { - for (size_t i = 0; i < n; i++) - ds_put_format (s, "[%s]", f[i]->marker); + csv_output_field__ (csv, ss_cstr (field)); } static void -csv_output_table_item_text (struct csv_driver *csv, - const struct table_item_text *text, - const char *leader) +csv_put_separator (struct csv_driver *csv) { - if (!text) - return; + if (csv->n_items++ > 0) + putc ('\n', csv->file); +} +static void +csv_output_lines (struct csv_driver *csv, const char *text_) +{ + struct substring text = ss_cstr (text_); + struct substring line; + size_t save_idx = 0; + while (ss_separate (text, ss_cstr ("\n"), &save_idx, &line)) + { + csv_output_field__ (csv, line); + putc ('\n', csv->file); + } +} + +static void +csv_output_table_cell (struct csv_driver *csv, const struct pivot_table *pt, + const struct table_cell *cell, const char *leader) +{ 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); + if (cell->font_style->markup) + { + char *t = output_get_text_from_markup (ds_cstr (&s)); + ds_assign_cstr (&s, t); + free (t); + } csv_output_field (csv, ds_cstr (&s)); ds_destroy (&s); - putc ('\n', csv->file); } static void -csv_put_separator (struct csv_driver *csv) +csv_output_table__ (struct csv_driver *csv, const struct pivot_table *pt, + const struct table *t, const char *leader) { - if (csv->n_items++ > 0) - putc ('\n', csv->file); + if (!t) + return; + + for (int y = 0; y < t->n[TABLE_VERT]; y++) + { + for (int 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 + csv_output_table_cell (csv, pt, &cell, !x ? leader : NULL); + } + putc ('\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); } static void @@ -188,86 +251,11 @@ csv_submit (struct output_driver *driver, if (is_table_item (output_item)) { - struct table_item *table_item = to_table_item (output_item); - const struct table *t = table_item_get_table (table_item); - int x, y; - - csv_put_separator (csv); + const struct pivot_table *pt = to_table_item (output_item)->pt; - if (csv->titles) - csv_output_table_item_text (csv, table_item_get_title (table_item), - "Table"); - - for (y = 0; y < table_nr (t); y++) - { - for (x = 0; x < table_nc (t); 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.n_contents == 1 - && cell.contents[0].text != NULL - && cell.contents[0].n_footnotes == 0) - csv_output_field (csv, cell.contents[0].text); - else - { - struct string s; - size_t i; - - ds_init_empty (&s); - for (i = 0; i < cell.n_contents; i++) - { - const struct cell_contents *c = &cell.contents[i]; - - if (i > 0) - ds_put_cstr (&s, "\n\n"); - - if (c->options & TAB_MARKUP) - { - char *t = output_get_text_from_markup (c->text); - ds_put_cstr (&s, t); - free (t); - } - else - ds_put_cstr (&s, c->text); - csv_format_footnotes (c->footnotes, c->n_footnotes, &s); - } - csv_output_field (csv, ds_cstr (&s)); - ds_destroy (&s); - } - - table_cell_free (&cell); - } - putc ('\n', csv->file); - } - - if (csv->captions) - csv_output_table_item_text (csv, table_item_get_caption (table_item), - "Caption"); - - const struct footnote **f; - size_t n_footnotes = table_collect_footnotes (table_item, &f); - if (n_footnotes) - { - fputs ("\nFootnotes:\n", csv->file); - - for (size_t i = 0; i < n_footnotes; i++) - if (f[i]) - { - csv_output_field (csv, f[i]->marker); - fputs (csv->separator, csv->file); - csv_output_field (csv, f[i]->content); - putc ('\n', csv->file); - } - - free (f); - } + size_t *layer_indexes; + PIVOT_OUTPUT_FOR_EACH_LAYER (layer_indexes, pt, true) + csv_output_table_layer (csv, pt, layer_indexes); } else if (is_text_item (output_item)) { @@ -279,15 +267,20 @@ csv_submit (struct output_driver *driver, return; csv_put_separator (csv); - if (text_item->markup) + + if (text_item->style.markup) { char *plain_text = output_get_text_from_markup (text); - csv_output_field (csv, plain_text); + csv_output_lines (csv, plain_text); free (plain_text); } else - csv_output_field (csv, text); - putc ('\n', csv->file); + 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)) {