From a8fdc033bbcb8c4e7a4f0d2c40c6b48a90f2dbe7 Mon Sep 17 00:00:00 2001 From: John Darrington Date: Fri, 8 Mar 2013 09:59:07 +0100 Subject: [PATCH] Fixed some more errors in the spreadsheet readers --- src/data/gnumeric-reader.c | 37 +++++++++++----------- src/data/gnumeric-reader.h | 4 +-- src/data/ods-reader.c | 55 +++++++++++++++++++++------------ src/data/ods-reader.h | 2 ++ src/data/spreadsheet-reader.c | 16 +++++++++- src/data/spreadsheet-reader.h | 6 ++-- src/language/data-io/get-data.c | 11 ++++--- 7 files changed, 82 insertions(+), 49 deletions(-) diff --git a/src/data/gnumeric-reader.c b/src/data/gnumeric-reader.c index 578ff8ab4b..cda95e5378 100644 --- a/src/data/gnumeric-reader.c +++ b/src/data/gnumeric-reader.c @@ -63,6 +63,7 @@ static void gnm_file_casereader_destroy (struct casereader *, void *); static struct ccase *gnm_file_casereader_read (struct casereader *, void *); + static const struct casereader_class gnm_file_casereader_class = { gnm_file_casereader_read, @@ -133,6 +134,23 @@ struct gnumeric_reader }; +void +gnumeric_destroy (struct spreadsheet *s) +{ + struct gnumeric_reader *r = s; + int i; + + for (i = 0; i < s->n_sheets; ++i) + { + xmlFree (r->sheets[i].name); + } + + free (r->sheets); + + free (r); +} + + const char * gnumeric_get_sheet_name (struct spreadsheet *s, int n) { @@ -175,7 +193,6 @@ gnumeric_get_sheet_range (struct spreadsheet *s, int n) static void gnm_file_casereader_destroy (struct casereader *reader UNUSED, void *r_) { - int i; struct gnumeric_reader *r = r_; if ( r == NULL) return ; @@ -188,18 +205,9 @@ gnm_file_casereader_destroy (struct casereader *reader UNUSED, void *r_) case_unref (r->first_case); caseproto_unref (r->proto); - - for (i = 0; i < r->spreadsheet.n_sheets; ++i) - { - xmlFree (r->sheets[i].name); - } - - free (r->sheets); - - - free (r); } + static void process_node (struct gnumeric_reader *r) { @@ -424,13 +432,6 @@ struct var_spec }; -void -gnumeric_destroy (struct spreadsheet *s) -{ - gnm_file_casereader_destroy (NULL, s); -} - - static void gnumeric_error_handler (void *ctx, const char *mesg, UNUSED xmlParserSeverities sev, xmlTextReaderLocatorPtr loc) diff --git a/src/data/gnumeric-reader.h b/src/data/gnumeric-reader.h index e0a5f5cad0..1f5a32e3a4 100644 --- a/src/data/gnumeric-reader.h +++ b/src/data/gnumeric-reader.h @@ -29,10 +29,10 @@ struct spreadsheet *gnumeric_probe (const char *filename, bool report_errors); const char * gnumeric_get_sheet_name (struct spreadsheet *s, int n); char * gnumeric_get_sheet_range (struct spreadsheet *s, int n); -void gnumeric_destroy (struct spreadsheet *); - struct casereader * gnumeric_make_reader (struct spreadsheet *spreadsheet, const struct spreadsheet_read_options *opts); +void gnumeric_destroy (struct spreadsheet *r); + #endif diff --git a/src/data/ods-reader.c b/src/data/ods-reader.c index 5f5c0eed93..5306691c6c 100644 --- a/src/data/ods-reader.c +++ b/src/data/ods-reader.c @@ -67,9 +67,9 @@ ods_open_reader (const struct spreadsheet_read_options *opts, #include "gl/xalloc.h" static void ods_file_casereader_destroy (struct casereader *, void *); - static struct ccase *ods_file_casereader_read (struct casereader *, void *); + static const struct casereader_class ods_file_casereader_class = { ods_file_casereader_read, @@ -105,6 +105,7 @@ struct ods_reader struct spreadsheet spreadsheet; struct zip_reader *zreader; xmlTextReaderPtr xtr; + int ref_cnt; enum reader_state state; int row; @@ -113,7 +114,7 @@ struct ods_reader int current_sheet; xmlChar *current_sheet_name; - const xmlChar *target_sheet_name; + xmlChar *target_sheet_name; int target_sheet_index; @@ -136,6 +137,27 @@ struct ods_reader struct string ods_errs; }; +void +ods_destroy (struct spreadsheet *s) +{ + struct ods_reader *r = s; + + if (--r->ref_cnt == 0) + { + int i; + + for (i = 0; i < r->n_allocated_sheets; ++i) + { + xmlFree (r->sheets[i].name); + } + + zip_reader_destroy (r->zreader); + free (r->sheets); + free (r); + } +} + + static bool reading_target_sheet (const struct ods_reader *r) @@ -209,7 +231,6 @@ ods_get_sheet_range (struct spreadsheet *s, int n) static void ods_file_casereader_destroy (struct casereader *reader UNUSED, void *r_) { - int i; struct ods_reader *r = r_; if ( r == NULL) return ; @@ -229,16 +250,14 @@ ods_file_casereader_destroy (struct casereader *reader UNUSED, void *r_) caseproto_unref (r->proto); xmlFree (r->current_sheet_name); + xmlFree (r->target_sheet_name); + + ods_destroy (r); +} + - for (i = 0; i < r->n_allocated_sheets; ++i) - { - xmlFree (r->sheets[i].name); - } - free (r->sheets); - free (r); -} static void process_node (struct ods_reader *r) @@ -483,7 +502,7 @@ get_sheet_count (struct zip_reader *zreader) return -1; mxtr = xmlReaderForIO ((xmlInputReadCallback) zip_member_read, - (xmlInputCloseCallback) zip_member_finish, + (xmlInputCloseCallback) NULL, meta, NULL, NULL, 0); while (1 == xmlTextReaderRead (mxtr)) @@ -533,11 +552,10 @@ init_reader (struct ods_reader *r, bool report_errors) if ( content == NULL) return false; - zip_member_ref (content); - if (r->xtr) xmlFreeTextReader (r->xtr); + zip_member_ref (content); xtr = xmlReaderForIO ((xmlInputReadCallback) zip_member_read, (xmlInputCloseCallback) zip_member_finish, content, NULL, NULL, @@ -582,6 +600,7 @@ ods_probe (const char *filename, bool report_errors) r = xzalloc (sizeof *r); r->zreader = zr; + r->ref_cnt = 1; if (! init_reader (r, report_errors)) { @@ -622,12 +641,12 @@ ods_make_reader (struct spreadsheet *spreadsheet, assert (r); r->read_names = opts->read_names; ds_init_empty (&r->ods_errs); - + ++r->ref_cnt; if ( !init_reader (r, true)) goto error; - if ( opts->cell_range ) + if (opts->cell_range) { if ( ! convert_cell_ref (opts->cell_range, &r->start_col, &r->start_row, @@ -647,7 +666,7 @@ ods_make_reader (struct spreadsheet *spreadsheet, } r->state = STATE_INIT; - r->target_sheet_name = BAD_CAST opts->sheet_name; + r->target_sheet_name = xmlStrdup (BAD_CAST opts->sheet_name); r->target_sheet_index = opts->sheet_index; r->row = r->col = 0; @@ -825,7 +844,6 @@ ods_make_reader (struct spreadsheet *spreadsheet, break; } - // zip_reader_destroy (zreader); for ( i = 0 ; i < n_var_specs ; ++i ) { @@ -846,8 +864,6 @@ ods_make_reader (struct spreadsheet *spreadsheet, error: - //zip_reader_destroy (zreader); - for ( i = 0 ; i < n_var_specs ; ++i ) { free (var_spec[i].firstval.type); @@ -862,7 +878,6 @@ ods_make_reader (struct spreadsheet *spreadsheet, r->spreadsheet.dict = NULL; ods_file_casereader_destroy (NULL, r); - return NULL; } diff --git a/src/data/ods-reader.h b/src/data/ods-reader.h index 3d939a8048..4acda231da 100644 --- a/src/data/ods-reader.h +++ b/src/data/ods-reader.h @@ -31,5 +31,7 @@ struct spreadsheet *ods_probe (const char *filename, bool report_errors); struct casereader * ods_make_reader (struct spreadsheet *spreadsheet, const struct spreadsheet_read_options *opts); +void ods_destroy (struct spreadsheet *s); + #endif diff --git a/src/data/spreadsheet-reader.c b/src/data/spreadsheet-reader.c index 4a85cb22dd..fc1dfa8dd5 100644 --- a/src/data/spreadsheet-reader.c +++ b/src/data/spreadsheet-reader.c @@ -18,6 +18,7 @@ #include "spreadsheet-reader.h" +#include #include "gnumeric-reader.h" #include "ods-reader.h" @@ -28,9 +29,22 @@ #include #include + void -spreadsheet_close (UNUSED struct spreadsheet *spreadsheet) +spreadsheet_destroy (struct spreadsheet *s) { + switch (s->type) + { + case SPREADSHEET_ODS: + ods_destroy (s); + break; + case SPREADSHEET_GNUMERIC: + gnumeric_destroy (s); + break; + default: + NOT_REACHED (); + break; + } } diff --git a/src/data/spreadsheet-reader.h b/src/data/spreadsheet-reader.h index 5cfd81d7e1..9a46b35e9e 100644 --- a/src/data/spreadsheet-reader.h +++ b/src/data/spreadsheet-reader.h @@ -30,9 +30,9 @@ struct casereeader; */ struct spreadsheet_read_options { - const char *sheet_name ; /* The name of the sheet to open (in UTF-8) */ + char *sheet_name ; /* The name of the sheet to open (in UTF-8) */ int sheet_index ; /* The index of the sheet to open (only used if sheet_name is NULL) */ - const char *cell_range ; /* The cell range (in UTF-8) */ + char *cell_range ; /* The cell range (in UTF-8) */ bool read_names ; /* True if the first row is to be used as the names of the variables */ int asw ; /* The width of string variables in the created dictionary */ }; @@ -79,7 +79,7 @@ char * spreadsheet_get_sheet_range (struct spreadsheet *s, int n); char *create_cell_ref (int col0, int row0, int coli, int rowi); -void spreadsheet_close (struct spreadsheet *); +void spreadsheet_destroy (struct spreadsheet *); diff --git a/src/language/data-io/get-data.c b/src/language/data-io/get-data.c index 2879e34a4b..daec18f41d 100644 --- a/src/language/data-io/get-data.c +++ b/src/language/data-io/get-data.c @@ -57,11 +57,12 @@ static int parse_get_psql (struct lexer *lexer, struct dataset *); int cmd_get_data (struct lexer *lexer, struct dataset *ds) { + struct spreadsheet_read_options opts; char *tok = NULL; lex_force_match (lexer, T_SLASH); if (!lex_force_match_id (lexer, "TYPE")) - return CMD_FAILURE; + goto error; lex_force_match (lexer, T_EQUALS); @@ -82,7 +83,7 @@ cmd_get_data (struct lexer *lexer, struct dataset *ds) char *filename = NULL; struct casereader *reader = NULL; struct dictionary *dict = NULL; - struct spreadsheet_read_options opts; + if (!parse_spreadsheet (lexer, &filename, &opts)) goto error; @@ -101,6 +102,7 @@ cmd_get_data (struct lexer *lexer, struct dataset *ds) goto error; reader = ods_make_reader (spreadsheet, &opts); dict = spreadsheet->dict; + ods_destroy (spreadsheet); } free (filename); @@ -113,15 +115,13 @@ cmd_get_data (struct lexer *lexer, struct dataset *ds) destroy_spreadsheet_read_info (&opts); return CMD_SUCCESS; } - destroy_spreadsheet_read_info (&opts); } else msg (SE, _("Unsupported TYPE %s."), tok); - - error: + destroy_spreadsheet_read_info (&opts); free (tok); return CMD_FAILURE; } @@ -682,4 +682,5 @@ static void destroy_spreadsheet_read_info (struct spreadsheet_read_options *opts) { free (opts->cell_range); + free (opts->sheet_name); } -- 2.30.2