X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fgnumeric-reader.c;h=9193cfb061c4949be89b8467877174bcbf1a0264;hb=bbec8db61a8288576c4d2f158c24c1e429a21ee4;hp=5e4b6978ef55ebc7c3239b438f8d564b1816ac05;hpb=3c6287003e07308c727d9ca13f759bfce33e0693;p=pspp diff --git a/src/data/gnumeric-reader.c b/src/data/gnumeric-reader.c index 5e4b6978ef..9193cfb061 100644 --- a/src/data/gnumeric-reader.c +++ b/src/data/gnumeric-reader.c @@ -28,12 +28,10 @@ #include "spreadsheet-reader.h" -#include "c-xvasprintf.h" - #if !GNM_SUPPORT struct casereader * -gnumeric_open_reader (struct spreadsheet_read_info *gri, struct spreadsheet_read_options *opts, struct dictionary **dict) +gnumeric_open_reader (const struct spreadsheet_read_options *opts, struct dictionary **dict) { msg (ME, _("Support for %s files was not compiled into this installation of PSPP"), "Gnumeric"); @@ -65,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, @@ -89,7 +88,8 @@ enum reader_state struct sheet_detail { - xmlChar *name; + /* The name of the sheet (utf8 encoding) */ + char *name; int start_col; int stop_col; @@ -104,6 +104,7 @@ struct sheet_detail struct gnumeric_reader { struct spreadsheet spreadsheet; + int ref_cnt; /* The libxml reader for this instance */ xmlTextReaderPtr xtr; @@ -134,19 +135,44 @@ struct gnumeric_reader }; +void +gnumeric_destroy (struct spreadsheet *s) +{ + struct gnumeric_reader *r = (struct gnumeric_reader *) s; + + +#if 0 + if (0 == --r->ref_cnt) + { + int i; + + for (i = 0; i < s->n_sheets; ++i) + { + xmlFree (r->sheets[i].name); + } + + free (r->sheets); + + free (r); + } +#endif +} + + const char * gnumeric_get_sheet_name (struct spreadsheet *s, int n) { struct gnumeric_reader *gr = (struct gnumeric_reader *) s; assert (n < s->n_sheets); - return gr->sheets[n].name; // Kludge: Assumes the encoding is utf8 + return gr->sheets[n].name; } static void process_node (struct gnumeric_reader *r); + char * gnumeric_get_sheet_range (struct spreadsheet *s, int n) { @@ -176,9 +202,11 @@ static void gnm_file_casereader_destroy (struct casereader *reader UNUSED, void *r_) { struct gnumeric_reader *r = r_; + if ( r == NULL) return ; +#if 0 if ( r->xtr) xmlFreeTextReader (r->xtr); r->xtr = NULL; @@ -188,19 +216,11 @@ gnm_file_casereader_destroy (struct casereader *reader UNUSED, void *r_) caseproto_unref (r->proto); -#if 0 - for (i = 0; i < r->spreadsheet.n_sheets; ++i) - { - xmlFree (r->sheets[i].name); - } - - free (r->sheets); - - - free (r); + gnumeric_destroy (&r->spreadsheet); #endif } + static void process_node (struct gnumeric_reader *r) { @@ -243,7 +263,7 @@ process_node (struct gnumeric_reader *r) } else if (XML_READER_TYPE_TEXT == r->node_type) { - r->sheets [r->spreadsheet.n_sheets - 1].name = xmlTextReaderValue (r->xtr); + r->sheets [r->spreadsheet.n_sheets - 1].name = CHAR_CAST (char *, xmlTextReaderValue (r->xtr)); } break; @@ -425,20 +445,14 @@ 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) { struct gnumeric_reader *r = ctx; - msg (MW, _("There was a problem whilst reading the Gnumeric file `%s' (near line %d): `%s'"), + msg (MW, _("There was a problem whilst reading the %s file `%s' (near line %d): `%s'"), + "Gnumeric", r->spreadsheet.file_name, xmlTextReaderLocatorLineNumber (loc), mesg); @@ -493,6 +507,7 @@ gnumeric_reopen (struct gnumeric_reader *r, const char *filename, bool show_erro r->row = r->col = -1; r->state = STATE_PRE_INIT; r->xtr = xtr; + r->ref_cnt++; /* Advance to the start of the workbook. This gives us some confidence that we are actually dealing with a gnumeric @@ -504,6 +519,7 @@ gnumeric_reopen (struct gnumeric_reader *r, const char *filename, bool show_erro process_node (r); } + if ( ret != 1) { /* Does not seem to be a gnumeric file */ @@ -514,6 +530,22 @@ gnumeric_reopen (struct gnumeric_reader *r, const char *filename, bool show_erro r->spreadsheet.type = SPREADSHEET_GNUMERIC; + if (show_errors) + { + const xmlChar *enc = xmlTextReaderConstEncoding (r->xtr); + xmlCharEncoding xce = xmlParseCharEncoding (CHAR_CAST (const char *, enc)); + + if ( XML_CHAR_ENCODING_UTF8 != xce) + { + /* I have been told that ALL gnumeric files are UTF8 encoded. If that is correct, this + can never happen. */ + msg (MW, _("The gnumeric file `%s' is encoded as %s instead of the usual UTF-8 encoding. " + "Any non-ascii characters will be incorrectly imported."), + r->spreadsheet.file_name, + enc); + } + } + return r; } @@ -529,9 +561,9 @@ gnumeric_probe (const char *filename, bool report_errors) struct casereader * gnumeric_make_reader (struct spreadsheet *spreadsheet, - const struct spreadsheet_read_info *gri, const struct spreadsheet_read_options *opts) { + int x = 0; struct gnumeric_reader *r = NULL; unsigned long int vstart = 0; int ret; @@ -545,6 +577,8 @@ gnumeric_make_reader (struct spreadsheet *spreadsheet, if (r->row != -1) r = gnumeric_reopen (r, NULL, true); + + if ( opts->cell_range ) { if ( ! convert_cell_ref (opts->cell_range, @@ -591,7 +625,7 @@ gnumeric_make_reader (struct spreadsheet *spreadsheet, n_cases = MIN (n_cases, r->stop_row - r->start_row + 1); } - if ( gri->read_names ) + if ( opts->read_names ) { r->start_row++; n_cases --; @@ -635,7 +669,7 @@ gnumeric_make_reader (struct spreadsheet *spreadsheet, if ( r->row < r->start_row) { - if ( gri->read_names ) + if ( opts->read_names ) { var_spec [idx].name = xstrdup (text); } @@ -645,8 +679,8 @@ gnumeric_make_reader (struct spreadsheet *spreadsheet, var_spec [idx].first_value = xmlStrdup (value); if (-1 == var_spec [idx].width ) - var_spec [idx].width = (gri->asw == -1) ? - ROUND_UP (strlen(text), SPREADSHEET_DEFAULT_WIDTH) : gri->asw; + var_spec [idx].width = (opts->asw == -1) ? + ROUND_UP (strlen(text), SPREADSHEET_DEFAULT_WIDTH) : opts->asw; } free (value); @@ -706,13 +740,15 @@ gnumeric_make_reader (struct spreadsheet *spreadsheet, r->first_case = case_create (r->proto); case_set_missing (r->first_case); - int x = 0; + for ( i = 0 ; i < n_var_specs ; ++i ) { + const struct variable *var; + if ( (var_spec[i].name == NULL) && (var_spec[i].first_value == NULL)) continue; - const struct variable *var = dict_get_var (r->dict, x++); + var = dict_get_var (r->dict, x++); convert_xml_string_to_value (r->first_case, var, var_spec[i].first_value); @@ -727,17 +763,6 @@ gnumeric_make_reader (struct spreadsheet *spreadsheet, free (var_spec); -#if 0 - if (opts->cell_range == NULL) - { - opts->cell_range = c_xasprintf ("%c%d:%c%ld", - r->start_col + 'A', - r->start_row, - r->stop_col + 'A' + caseproto_get_n_widths (r->proto), - r->start_row + n_cases); - } -#endif - return casereader_create_sequential (NULL, r->proto,