ODS reader: Deal with case where /READNAMES vs. non-unity column spans.
authorJohn Darrington <john@darrington.wattle.id.au>
Fri, 6 Jul 2018 10:19:45 +0000 (12:19 +0200)
committerJohn Darrington <john@darrington.wattle.id.au>
Fri, 6 Jul 2018 10:19:45 +0000 (12:19 +0200)
* 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.

src/data/ods-reader.c
tests/automake.mk
tests/language/data-io/get-data-spreadsheet.at
tests/language/data-io/readnames.ods [new file with mode: 0644]

index 387bea00ac28c2d319546046afdf77f82d0c3198..ce9310a230b23385891eaed984f8ce929bdc7819 100644 (file)
@@ -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);
            }
index 4a05bea98087dc66e661343a2586f9ea4ad31858..7c7bdc74965410fafced84b879ae81ba067c4dd7 100644 (file)
@@ -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*
index 6c838d99bdcaab4fc9492c1aa51e74f9826384c6..eca194a02dde0508735b318a1191a7ebc675fd54 100644 (file)
@@ -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 (file)
index 0000000..3cccb2d
Binary files /dev/null and b/tests/language/data-io/readnames.ods differ