X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Foutput%2Fcsv.c;h=626dc2fa5ad2c7a7b9a15898908338bed37ba378;hb=refs%2Fbuilds%2F20100824040503%2Fpspp;hp=158c78952233282e4580d1f5814f80f498c27db8;hpb=dfd1972f7bcb550a4fc3b05dbe7e71d12334b0a7;p=pspp diff --git a/src/output/csv.c b/src/output/csv.c index 158c789522..626dc2fa5a 100644 --- a/src/output/csv.c +++ b/src/output/csv.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2009 Free Software Foundation, Inc. + Copyright (C) 2009, 2010 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,15 +19,17 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "data/file-name.h" +#include "libpspp/assertion.h" +#include "libpspp/compiler.h" +#include "libpspp/message.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/table-item.h" +#include "output/table-provider.h" #include "gl/error.h" #include "gl/xalloc.h" @@ -42,16 +44,18 @@ struct csv_driver struct output_driver driver; char *separator; /* Comma or tab. */ - char *file_name; /* Output file name. */ + char *command_name; /* Current command. */ FILE *file; /* Output file. */ - bool reported_error; /* Reported file open error? */ + int n_items; /* Number of items output so far. */ }; +static const struct output_driver_class csv_driver_class; + static struct csv_driver * csv_driver_cast (struct output_driver *driver) { - assert (driver->class == &csv_class); + assert (driver->class == &csv_driver_class); return UP_CAST (driver, struct csv_driver, driver); } @@ -63,7 +67,7 @@ opt (struct output_driver *d, struct string_map *options, const char *key, } static struct output_driver * -csv_create (const char *name, enum output_device_type device_type, +csv_create (const char *file_name, enum settings_output_devices device_type, struct string_map *o) { struct output_driver *d; @@ -71,12 +75,19 @@ csv_create (const char *name, enum output_device_type device_type, csv = xzalloc (sizeof *csv); d = &csv->driver; - output_driver_init (&csv->driver, &csv_class, name, device_type); + output_driver_init (&csv->driver, &csv_driver_class, file_name, device_type); csv->separator = parse_string (opt (d, o, "separator", ",")); - csv->file_name = parse_string (opt (d, o, "output-file", "pspp.csv")); - csv->file = NULL; - csv->reported_error = false; + csv->file_name = xstrdup (file_name); + csv->file = fn_open (csv->file_name, "w"); + csv->n_items = 0; + + if (csv->file == NULL) + { + error (0, errno, _("error opening output file \"%s\""), csv->file_name); + output_driver_destroy (d); + return NULL; + } return d; } @@ -86,10 +97,11 @@ csv_destroy (struct output_driver *driver) { struct csv_driver *csv = csv_driver_cast (driver); + if (csv->file != NULL) + fn_close (csv->file_name, csv->file); + free (csv->separator); free (csv->file_name); - if (csv->file != NULL) - fclose (csv->file); free (csv); } @@ -142,25 +154,11 @@ csv_output_field_format (FILE *file, const char *format, ...) free (s); } -static bool -csv_open_file (struct csv_driver *csv) +static void +csv_put_separator (struct csv_driver *csv) { - if (csv->file == NULL) - { - csv->file = fn_open (csv->file_name, "w"); - if (csv->file == NULL) - { - if (!csv->reported_error) - error (0, errno, _("csv: opening output file \"%s\""), - csv->file_name); - csv->reported_error = true; - return false; - } - } - else + if (csv->n_items++ > 0) putc ('\n', csv->file); - - return true; } static void @@ -169,6 +167,8 @@ csv_submit (struct output_driver *driver, { struct csv_driver *csv = csv_driver_cast (driver); + output_driver_track_current_command (output_item, &csv->command_name); + if (is_table_item (output_item)) { struct table_item *table_item = to_table_item (output_item); @@ -176,8 +176,7 @@ csv_submit (struct output_driver *driver, const struct table *t = table_item_get_table (table_item); int x, y; - if (!csv_open_file (csv)) - return; + csv_put_separator (csv); if (caption != NULL) { @@ -216,7 +215,7 @@ csv_submit (struct output_driver *driver, || type == TEXT_ITEM_SYNTAX) return; - csv_open_file (csv); + csv_put_separator (csv); switch (type) { case TEXT_ITEM_TITLE: @@ -233,12 +232,23 @@ csv_submit (struct output_driver *driver, } putc ('\n', csv->file); } + else if (is_message_item (output_item)) + { + const struct message_item *message_item = to_message_item (output_item); + const struct msg *msg = message_item_get_msg (message_item); + char *s = msg_to_string (msg, csv->command_name); + csv_put_separator (csv); + csv_output_field (csv->file, s); + free (s); + putc ('\n', csv->file); + } } -const struct output_driver_class csv_class = +struct output_driver_factory csv_driver_factory = { "csv", csv_create }; + +static const struct output_driver_class csv_driver_class = { "csv", - csv_create, csv_destroy, csv_submit, csv_flush,