From: John Darrington Date: Fri, 6 Jul 2018 10:19:45 +0000 (+0200) Subject: ODS reader: Deal with case where /READNAMES vs. non-unity column spans. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6ee30c166727634ef579354e29eff96f70675418;p=pspp ODS reader: Deal with case where /READNAMES vs. non-unity column spans. * src/data/ods-reader.c (ods_make_reader): Populate var_specs for the entire column span. * tests/language/data-io/readnames.ods: New file * tests/automake.mk: Add it. * tests/language/data-io/get-data-spreadsheet.at: New test. --- diff --git a/src/data/ods-reader.c b/src/data/ods-reader.c index 387bea00ac..ce9310a230 100644 --- a/src/data/ods-reader.c +++ b/src/data/ods-reader.c @@ -401,7 +401,7 @@ process_node (struct ods_reader *or, struct state_data *r) or->sheets[r->current_sheet].stop_row = r->row - 1; - if ( or->sheets[r->current_sheet].stop_col < r->col - 1) + if ( or->sheets[r->current_sheet].stop_col < r->col - 1) or->sheets[r->current_sheet].stop_col = r->col - 1; if (XML_READER_TYPE_END_ELEMENT == r->node_type) @@ -721,17 +721,15 @@ ods_make_reader (struct spreadsheet *spreadsheet, { while (1 == xmlTextReaderRead (r->rsd.xtr)) { - int idx; - process_node (r, &r->rsd); /* If the row is finished then stop for now */ if (r->rsd.state == STATE_TABLE && r->rsd.row > r->start_row) break; - idx = r->rsd.col - r->start_col -1 ; + int idx = r->rsd.col - r->start_col - 1; - if ( idx < 0) + if (idx < 0) continue; if (r->stop_col != -1 && idx > r->stop_col - r->start_col) @@ -742,8 +740,7 @@ ods_make_reader (struct spreadsheet *spreadsheet, XML_READER_TYPE_TEXT == r->rsd.node_type) { xmlChar *value = xmlTextReaderValue (r->rsd.xtr); - - if ( idx >= n_var_specs) + if (idx >= n_var_specs) { var_spec = xrealloc (var_spec, sizeof (*var_spec) * (idx + 1)); @@ -753,11 +750,14 @@ ods_make_reader (struct spreadsheet *spreadsheet, (idx - n_var_specs + 1) * sizeof (*var_spec)); n_var_specs = idx + 1; } - var_spec[idx].firstval.text = 0; - var_spec[idx].firstval.value = 0; - var_spec[idx].firstval.type = 0; - - var_spec [idx].name = strdup (CHAR_CAST (const char *, value)); + for (int i = 0; i < r->rsd.col_span; ++i) + { + var_spec[idx - i].firstval.text = 0; + var_spec[idx - i].firstval.value = 0; + var_spec[idx - i].firstval.type = 0; + var_spec[idx - i].name = + strdup (CHAR_CAST (const char *, value)); + } xmlFree (value); } diff --git a/tests/automake.mk b/tests/automake.mk index 4a05bea980..7c7bdc7496 100644 --- a/tests/automake.mk +++ b/tests/automake.mk @@ -278,6 +278,7 @@ EXTRA_DIST += \ tests/language/data-io/Book1.gnm.unzipped \ tests/language/data-io/test.ods \ tests/language/data-io/newone.ods \ + tests/language/data-io/readnames.ods \ tests/language/stats/llz.zsav CLEANFILES += *.save pspp.* foo* diff --git a/tests/language/data-io/get-data-spreadsheet.at b/tests/language/data-io/get-data-spreadsheet.at index 6c838d99bd..eca194a02d 100644 --- a/tests/language/data-io/get-data-spreadsheet.at +++ b/tests/language/data-io/get-data-spreadsheet.at @@ -385,3 +385,35 @@ AT_CHECK([pspp -O format=csv crash.sps], [0], [ignore]) AT_CLEANUP + +AT_SETUP([GET DATA /TYPE=ODS readnames]) + +dnl Check for a bug where in the ODS reader /READNAMES incorrectly +dnl dealt with repeated names. +AT_CHECK([cp $top_srcdir/tests/language/data-io/readnames.ods this.ods])dnl + +AT_DATA([readnames.sps],[dnl +GET DATA /TYPE=ODS /FILE='this.ods' /CELLRANGE=RANGE 'A1:H8' /READNAMES=ON +DISPLAY DICTIONARY. +LIST. +]) + + +AT_CHECK([pspp -O format=csv readnames.sps], [0], +[Variable,Description,Position +freda,Format: F8.2,1 +fred,Format: F8.2,2 +fred_A,Format: F8.2,3 +fred_B,Format: F8.2,4 +fred_C,Format: F8.2,5 +fred_D,Format: F8.2,6 +fred_E,Format: F8.2,7 + +Table: Data List +freda,fred,fred_A,fred_B,fred_C,fred_D,fred_E +1.00,2.00,3.00,4.00,5.00,6.00,7.00 +8.00,9.00,10.00,11.00,12.00,13.00,14.00 +]) + +AT_CLEANUP + diff --git a/tests/language/data-io/readnames.ods b/tests/language/data-io/readnames.ods new file mode 100644 index 0000000000..3cccb2da06 Binary files /dev/null and b/tests/language/data-io/readnames.ods differ