X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=src%2Fdata%2Fgnumeric-reader.c;h=69dd23689fc6b979d54540c23ae65511b46a885f;hb=8f5194875a0a3d41fef91825fd8378bb004d6f51;hp=aa0e161d4aff067d8261706cef2ff51a35a768d9;hpb=e37c7ed26e2f4ee22e2648b72f7a4fc8a5c6fa7e;p=pspp diff --git a/src/data/gnumeric-reader.c b/src/data/gnumeric-reader.c index aa0e161d4a..69dd23689f 100644 --- a/src/data/gnumeric-reader.c +++ b/src/data/gnumeric-reader.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2007, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. + Copyright (C) 2007, 2009, 2010, 2011, 2012, 2013 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 @@ -90,6 +90,14 @@ enum reader_state struct sheet_detail { xmlChar *name; + + int start_col; + int stop_col; + int start_row; + int stop_row; + + int maxcol; + int maxrow; }; @@ -97,8 +105,10 @@ struct gnumeric_reader { struct spreadsheet spreadsheet; + /* The libxml reader for this instance */ xmlTextReaderPtr xtr; + /* An internal state variable */ enum reader_state state; int row; @@ -133,17 +143,34 @@ gnumeric_get_sheet_name (struct spreadsheet *s, int n) return gr->sheets[n].name; } -const char * + +static void process_node (struct gnumeric_reader *r); + + +char * gnumeric_get_sheet_range (struct spreadsheet *s, int n) { + int ret; struct gnumeric_reader *gr = (struct gnumeric_reader *) s; + assert (n < s->sheets); - return "I havent the fogiest idea"; -} + while ( + (gr->sheets[n].stop_col == -1) + && + (1 == (ret = xmlTextReaderRead (gr->xtr))) + ) + { + process_node (gr); + } -static void process_node (struct gnumeric_reader *r); + return create_cell_ref ( + gr->sheets[n].start_col, + gr->sheets[n].start_row, + gr->sheets[n].stop_col, + gr->sheets[n].stop_row); +} static void @@ -185,6 +212,7 @@ process_node (struct gnumeric_reader *r) switch ( r->state) { case STATE_PRE_INIT: + r->sheet_index = -1; if (0 == xmlStrcasecmp (name, _xml("gnm:SheetNameIndex")) && XML_READER_TYPE_ELEMENT == r->node_type) { @@ -197,8 +225,11 @@ process_node (struct gnumeric_reader *r) if (0 == xmlStrcasecmp (name, _xml("gnm:SheetName")) && XML_READER_TYPE_ELEMENT == r->node_type) { + struct sheet_detail *sd ; r->spreadsheet.sheets++; r->sheets = xrealloc (r->sheets, r->spreadsheet.sheets * sizeof *r->sheets); + sd = &r->sheets[r->spreadsheet.sheets - 1]; + sd->start_col = sd->stop_col = sd->start_row = sd->stop_row = -1; } else if (0 == xmlStrcasecmp (name, _xml("gnm:SheetNameIndex")) && XML_READER_TYPE_END_ELEMENT == r->node_type) @@ -232,16 +263,25 @@ process_node (struct gnumeric_reader *r) { r->state = STATE_INIT; } + else if (0 == xmlStrcasecmp (name, _xml("gnm:Sheet")) && + XML_READER_TYPE_END_ELEMENT == r->node_type) + { + r->state = STATE_INIT; + } else if (XML_READER_TYPE_TEXT == r->node_type) { - if ( r->target_sheet != NULL) + if ( r->target_sheet != NULL) { xmlChar *value = xmlTextReaderValue (r->xtr); if ( 0 == xmlStrcmp (value, r->target_sheet)) r->state = STATE_SHEET_FOUND; free (value); } - else if (r->target_sheet_index == r->sheet_index) + else if (r->target_sheet_index == r->sheet_index + 1) + { + r->state = STATE_SHEET_FOUND; + } + else if (r->target_sheet_index == -1) { r->state = STATE_SHEET_FOUND; } @@ -268,7 +308,7 @@ process_node (struct gnumeric_reader *r) else if (0 == xmlStrcasecmp (name, _xml("gnm:Sheet")) && XML_READER_TYPE_END_ELEMENT == r->node_type) { - r->state = STATE_INIT; + r->state = STATE_INIT; } break; case STATE_MAXROW: @@ -280,6 +320,7 @@ process_node (struct gnumeric_reader *r) else if (r->node_type == XML_READER_TYPE_TEXT) { xmlChar *value = xmlTextReaderValue (r->xtr); + r->sheets[r->sheet_index].maxrow = _xmlchar_to_int (value); xmlFree (value); } break; @@ -292,6 +333,7 @@ process_node (struct gnumeric_reader *r) else if (r->node_type == XML_READER_TYPE_TEXT) { xmlChar *value = xmlTextReaderValue (r->xtr); + r->sheets[r->sheet_index].maxcol = _xmlchar_to_int (value); xmlFree (value); } break; @@ -312,11 +354,23 @@ process_node (struct gnumeric_reader *r) attr = xmlTextReaderGetAttribute (r->xtr, _xml ("Row")); r->row = _xmlchar_to_int (attr); free (attr); + if (r->sheets[r->sheet_index].start_row == -1) + { + r->sheets[r->sheet_index].start_row = r->row; + } + + if (r->sheets[r->sheet_index].start_col == -1) + { + r->sheets[r->sheet_index].start_col = r->col; + } } else if (0 == xmlStrcasecmp (name, _xml("gnm:Cells")) && XML_READER_TYPE_END_ELEMENT == r->node_type) - r->state = STATE_SHEET_NAME; - + { + r->sheets[r->sheet_index].stop_col = r->col; + r->sheets[r->sheet_index].stop_row = r->row; + r->state = STATE_SHEET_NAME; + } break; case STATE_CELL: if (0 == xmlStrcasecmp (name, _xml("gnm:Cell")) && @@ -373,14 +427,24 @@ gnumeric_destroy (struct spreadsheet *s) gnm_file_casereader_destroy (NULL, s); } -struct spreadsheet * -gnumeric_probe (const char *filename) -{ + +static struct gnumeric_reader * +gnumeric_reopen (struct gnumeric_reader *r, const char *filename) +{ int ret; - struct gnumeric_reader *r = NULL; + xmlTextReaderPtr xtr; + gzFile gz; + + assert (r == NULL || filename == NULL); + + if (r && r->xtr) + xmlFreeTextReader (r->xtr); - gzFile gz = gzopen (filename, "r"); + if (filename) + gz = gzopen (filename, "r"); + else + gz = gzopen ( r->spreadsheet.file_name, "r"); if (NULL == gz) return NULL; @@ -390,14 +454,24 @@ gnumeric_probe (const char *filename) NULL, NULL, 0); if (xtr == NULL) - return NULL; + { + gzclose (gz); + return NULL; + } - r = xzalloc (sizeof *r); - - r->xtr = xtr; - r->spreadsheet.sheets = -1; - r->state = STATE_PRE_INIT; + if (r == NULL) + { + r = xzalloc (sizeof *r); + r->spreadsheet.sheets = -1; + r->spreadsheet.file_name = filename; + } + r->target_sheet = NULL; + r->target_sheet_index = -1; + + r->row = r->col = -1; + r->state = STATE_PRE_INIT; + r->xtr = xtr; /* Advance to the start of the workbook. This gives us some confidence that we are actually dealing with a gnumeric @@ -409,17 +483,17 @@ gnumeric_probe (const char *filename) process_node (r); } - if (ret != 1) - { - /* Not a gnumeric spreadsheet */ - free (r); - gzclose (gz); - return NULL; - } - r->spreadsheet.type = SPREADSHEET_GNUMERIC; - r->spreadsheet.file_name = filename; - + + return r; +} + + +struct spreadsheet * +gnumeric_probe (const char *filename) +{ + struct gnumeric_reader *r = gnumeric_reopen (NULL, filename); + return &r->spreadsheet; } @@ -439,6 +513,9 @@ gnumeric_make_reader (struct spreadsheet *spreadsheet, r = (struct gnumeric_reader *) (spreadsheet); + if (r->row != -1) + r = gnumeric_reopen (r, NULL); + if ( opts->cell_range ) { if ( ! convert_cell_ref (opts->cell_range, @@ -458,11 +535,10 @@ gnumeric_make_reader (struct spreadsheet *spreadsheet, r->stop_row = -1; } - r->target_sheet = BAD_CAST opts->sheet_name; r->target_sheet_index = opts->sheet_index; r->row = r->col = -1; - r->sheet_index = 0; + r->sheet_index = -1; /* Advance to the start of the cells for the target sheet */ while ( (r->state != STATE_CELL || r->row < r->start_row ) @@ -479,7 +555,6 @@ gnumeric_make_reader (struct spreadsheet *spreadsheet, free (value); } - /* If a range has been given, then use that to calculate the number of cases */ if ( opts->cell_range)