ods-reader: Use proper function type for xml read callback.
[pspp] / src / data / ods-reader.c
index 736985ea8be29a8c6bc4947de7591e7f889f89b5..457edeb4fcefff391551e1e3f92497cc23ef5e15 100644 (file)
 
 #include <config.h>
 
-#include "libpspp/message.h"
-#include "libpspp/misc.h"
-#include "libpspp/assertion.h"
-
-#include "data/data-in.h"
-
-#include "gl/c-strtod.h"
-#include "gl/minmax.h"
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-#define N_(msgid) (msgid)
-
 #include "ods-reader.h"
 #include "spreadsheet-reader.h"
 
-#if !ODF_READ_SUPPORT
-
-struct spreadsheet *
-ods_probe (const char *filename, bool report_errors)
-{
-  if (report_errors)
-    msg (ME, _("Support for %s files was not compiled into this installation of PSPP"), "OpenDocument");
-
-  return NULL;
-}
-
-const char *
-ods_get_sheet_name (struct spreadsheet *s, int n)
-{
-  return NULL;
-}
-
-char *
-ods_get_sheet_range (struct spreadsheet *s, int n)
-{
-  return NULL;
-}
-
-struct casereader *
-ods_make_reader (struct spreadsheet *spreadsheet,
-                const struct spreadsheet_read_options *opts)
-{
-  return NULL;
-}
-
-
-void
-ods_unref (struct spreadsheet *r)
-{
-}
-
-#else
-
-#include "libpspp/zip-reader.h"
-
-
 #include <assert.h>
 #include <stdbool.h>
 #include <errno.h>
 #include <libxml/xmlreader.h>
 #include <zlib.h>
 
-#include "data/format.h"
 #include "data/case.h"
 #include "data/casereader-provider.h"
+#include "data/data-in.h"
 #include "data/dictionary.h"
+#include "data/format.h"
 #include "data/identifier.h"
 #include "data/value.h"
 #include "data/variable.h"
+#include "libpspp/assertion.h"
 #include "libpspp/i18n.h"
+#include "libpspp/message.h"
+#include "libpspp/misc.h"
 #include "libpspp/str.h"
+#include "libpspp/zip-reader.h"
 
+#include "gl/c-strtod.h"
+#include "gl/minmax.h"
 #include "gl/xalloc.h"
 
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+#define N_(msgid) (msgid)
+
 static void ods_file_casereader_destroy (struct casereader *, void *);
 static struct ccase *ods_file_casereader_read (struct casereader *, void *);
 
@@ -196,7 +153,7 @@ ods_unref (struct spreadsheet *s)
          xmlFree (r->sheets[i].name);
        }
 
-      dict_destroy (r->dict);
+      dict_unref (r->dict);
 
       zip_reader_destroy (r->zreader);
       free (r->sheets);
@@ -444,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)
@@ -550,6 +507,12 @@ convert_xml_to_value (struct ccase *c, const struct variable *var,
     }
 }
 
+static int
+xml_reader_for_zip_member (void *zm_, char *buffer, int len)
+{
+  struct zip_member *zm = zm_;
+  return zip_member_read (zm, buffer, len);
+}
 
 /* Try to find out how many sheets there are in the "workbook" */
 static int
@@ -562,9 +525,7 @@ get_sheet_count (struct zip_reader *zreader)
   if ( meta == NULL)
     return -1;
 
-  mxtr = xmlReaderForIO ((xmlInputReadCallback) zip_member_read,
-                        (xmlInputCloseCallback) NULL,
-                        meta,   NULL, NULL, 0);
+  mxtr = xmlReaderForIO (xml_reader_for_zip_member, NULL, meta, NULL, NULL, 0);
 
   while (1 == xmlTextReaderRead (mxtr))
     {
@@ -613,9 +574,7 @@ init_reader (struct ods_reader *r, bool report_errors)
   if ( content == NULL)
     return NULL;
 
-  xtr = xmlReaderForIO ((xmlInputReadCallback) zip_member_read,
-                       (xmlInputCloseCallback) NULL,
-                       content,   NULL, NULL,
+  xtr = xmlReaderForIO (xml_reader_for_zip_member, NULL, content, NULL, NULL,
                        report_errors ? 0 : (XML_PARSE_NOERROR | XML_PARSE_NOWARNING) );
 
   if ( xtr == NULL)
@@ -764,17 +723,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)
@@ -785,8 +742,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));
 
@@ -796,11 +752,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);
            }
@@ -1044,4 +1003,3 @@ ods_file_casereader_read (struct casereader *reader UNUSED, void *r_)
 
   return c;
 }
-#endif