changeset 20070:09ed6f7538dd

avoid needing to include hdf5 in public header files (bug #44370, #43180) * oct-hdf5-id.cc, oct-hdf5-id.h: New files. * libinterp/corefcn/module.mk: Update. * libgui/src/module.mk (src_libgui_src_la_CPPFLAGS): Remove $(HDF5_CPPFLAGS) from the list. * load-save.h (enum load_save_format_type): Always include LS_HDF5 in the list of values. * ls-hdf5.cc (read_hdf5_data, save_hdf5_data): Call check_hdf5_id_type. * oct-hdf5.h: Also #define HDF5_SAVE_TYPE. * ov.h, ov-base.h: Include oct-hdf5-id.h instead of oct-hdf5.h. Always declare load_hdf5 and save_hdf5 functions. * ov-base-int.cc, ov-base-int.h, ov-base.cc, ov-bool-mat.cc, ov-bool-mat.h, ov-bool-sparse.cc, ov-bool-sparse.h, ov-bool.cc, ov-bool.h, ov-cell.cc, ov-cell.h, ov-class.cc, ov-class.h, ov-complex.cc, ov-complex.h, ov-cx-mat.cc, ov-cx-mat.h, ov-cx-sparse.cc, ov-cx-sparse.h, ov-fcn-handle.cc, ov-fcn-handle.h, ov-fcn-inline.cc, ov-fcn-inline.h, ov-float.cc, ov-float.h, ov-flt-complex.cc, ov-flt-complex.h, ov-flt-cx-mat.cc, ov-flt-cx-mat.h, ov-flt-re-mat.cc, ov-flt-re-mat.h, ov-int16.cc, ov-int32.cc, ov-int64.cc, ov-int8.cc, ov-lazy-idx.h, ov-oncleanup.cc, ov-oncleanup.h, ov-range.cc ov-range.h, ov-re-mat.cc, ov-re-mat.h, ov-re-sparse.cc, ov-re-sparse.h, ov-scalar.cc, ov-scalar.h, ov-str-mat.cc, ov-str-mat.h, ov-struct.cc, ov-struct.h, ov-uint16.cc, ov-uint32.cc, ov-uint64.cc, ov-uint8.cc: Move #ifdef HAVE_HDF5 inside load_hdf5 and save_hdf5 functions. Always declare and define load_hdf5 and save_hdf5 functions.
author John W. Eaton <jwe@octave.org> and Mike Miller <mtmiller@ieee.org>
date Thu, 26 Feb 2015 10:49:20 -0500
parents 6b851f6acd55
children 17d647821d61
files libgui/src/module.mk libinterp/corefcn/load-save.h libinterp/corefcn/ls-hdf5.cc libinterp/corefcn/module.mk libinterp/corefcn/oct-hdf5-id.cc libinterp/corefcn/oct-hdf5-id.h libinterp/corefcn/oct-hdf5.h libinterp/octave-value/ov-base-int.cc libinterp/octave-value/ov-base-int.h libinterp/octave-value/ov-base.cc libinterp/octave-value/ov-base.h libinterp/octave-value/ov-bool-mat.cc libinterp/octave-value/ov-bool-mat.h libinterp/octave-value/ov-bool-sparse.cc libinterp/octave-value/ov-bool-sparse.h libinterp/octave-value/ov-bool.cc libinterp/octave-value/ov-bool.h libinterp/octave-value/ov-cell.cc libinterp/octave-value/ov-cell.h libinterp/octave-value/ov-class.cc libinterp/octave-value/ov-class.h libinterp/octave-value/ov-complex.cc libinterp/octave-value/ov-complex.h libinterp/octave-value/ov-cx-mat.cc libinterp/octave-value/ov-cx-mat.h libinterp/octave-value/ov-cx-sparse.cc libinterp/octave-value/ov-cx-sparse.h libinterp/octave-value/ov-fcn-handle.cc libinterp/octave-value/ov-fcn-handle.h libinterp/octave-value/ov-fcn-inline.cc libinterp/octave-value/ov-fcn-inline.h libinterp/octave-value/ov-float.cc libinterp/octave-value/ov-float.h libinterp/octave-value/ov-flt-complex.cc libinterp/octave-value/ov-flt-complex.h libinterp/octave-value/ov-flt-cx-mat.cc libinterp/octave-value/ov-flt-cx-mat.h libinterp/octave-value/ov-flt-re-mat.cc libinterp/octave-value/ov-flt-re-mat.h libinterp/octave-value/ov-int16.cc libinterp/octave-value/ov-int32.cc libinterp/octave-value/ov-int64.cc libinterp/octave-value/ov-int8.cc libinterp/octave-value/ov-lazy-idx.h libinterp/octave-value/ov-oncleanup.cc libinterp/octave-value/ov-oncleanup.h libinterp/octave-value/ov-range.cc libinterp/octave-value/ov-range.h libinterp/octave-value/ov-re-mat.cc libinterp/octave-value/ov-re-mat.h libinterp/octave-value/ov-re-sparse.cc libinterp/octave-value/ov-re-sparse.h libinterp/octave-value/ov-scalar.cc libinterp/octave-value/ov-scalar.h libinterp/octave-value/ov-str-mat.cc libinterp/octave-value/ov-str-mat.h libinterp/octave-value/ov-struct.cc libinterp/octave-value/ov-struct.h libinterp/octave-value/ov-uint16.cc libinterp/octave-value/ov-uint32.cc libinterp/octave-value/ov-uint64.cc libinterp/octave-value/ov-uint8.cc libinterp/octave-value/ov.h
diffstat 63 files changed, 603 insertions(+), 319 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/module.mk
+++ b/libgui/src/module.mk
@@ -183,7 +183,6 @@
   $(AM_CPPFLAGS) \
   $(FT2_CPPFLAGS) \
   $(FONTCONFIG_CPPFLAGS) \
-  $(HDF5_CPPFLAGS) \
   @OCTGUI_DLL_DEFS@ \
   @QT_CPPFLAGS@ \
   -I$(srcdir)/qterminal/libqterminal \
--- a/libinterp/corefcn/load-save.h
+++ b/libinterp/corefcn/load-save.h
@@ -41,9 +41,7 @@
   LS_MAT_BINARY,
   LS_MAT5_BINARY,
   LS_MAT7_BINARY,
-#ifdef HAVE_HDF5
   LS_HDF5,
-#endif /* HAVE_HDF5 */
   LS_UNKNOWN
 };
 
--- a/libinterp/corefcn/ls-hdf5.cc
+++ b/libinterp/corefcn/ls-hdf5.cc
@@ -55,6 +55,7 @@
 #include "error.h"
 #include "gripes.h"
 #include "load-save.h"
+#include "oct-hdf5-id.h"
 #include "oct-obj.h"
 #include "oct-map.h"
 #include "ov-cell.h"
@@ -587,6 +588,8 @@
                 bool& global, octave_value& tc, std::string& doc,
                 const string_vector& argv, int argv_idx, int argc)
 {
+  check_hdf5_id_type ();
+
   std::string retval;
 
   doc.resize (0);
@@ -952,6 +955,8 @@
                 const std::string& name, const std::string& doc,
                 bool mark_as_global, bool save_as_floats)
 {
+  check_hdf5_id_type ();
+
   hdf5_ofstream& hs = dynamic_cast<hdf5_ofstream&> (os);
 
   return add_hdf5_data (hs.file_id, tc, name, doc,
--- a/libinterp/corefcn/module.mk
+++ b/libinterp/corefcn/module.mk
@@ -82,6 +82,7 @@
   corefcn/oct-fstrm.h \
   corefcn/oct-handle.h \
   corefcn/oct-hdf5.h \
+  corefcn/oct-hdf5-id.h \
   corefcn/oct-hist.h \
   corefcn/oct-iostrm.h \
   corefcn/oct-lvalue.h \
@@ -212,6 +213,7 @@
   corefcn/mgorth.cc \
   corefcn/nproc.cc \
   corefcn/oct-fstrm.cc \
+  corefcn/oct-hdf5-id.cc \
   corefcn/oct-hist.cc \
   corefcn/oct-iostrm.cc \
   corefcn/oct-lvalue.cc \
new file mode 100644
--- /dev/null
+++ b/libinterp/corefcn/oct-hdf5-id.cc
@@ -0,0 +1,56 @@
+/*
+
+Copyright (C) 2015 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "error.h"
+#include "oct-hdf5.h"
+#include "oct-hdf5-id.h"
+
+bool
+check_hdf5_id_type (bool warn)
+{
+  static bool checked = false;
+  static bool ok = false;
+
+  if (! checked)
+    {
+#if defined (HAVE_HDF5)
+      ok = sizeof (octave_hdf5_id) >= sizeof (hid_t);
+
+      if (warn && ! ok)
+        warning_with_id
+          ("Octave:internal",
+           "the size of octave_hdf5_id is smaller than the size of HDF5 hid_t");
+#else
+      warning_with_id
+        ("Octave:internal",
+         "check_hdf5_id_type called but Octave was not compiled with support for HDF5");
+#endif
+
+      checked = true;
+    }
+
+  return ok;
+}
new file mode 100644
--- /dev/null
+++ b/libinterp/corefcn/oct-hdf5-id.h
@@ -0,0 +1,30 @@
+/*
+
+Copyright (C) 2015 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_oct_hdf5_id_h)
+#define octave_oct_hdf5_id_h 1
+
+typedef int octave_hdf5_id;
+
+extern bool check_hdf5_id_type (bool warn = true);
+
+#endif
--- a/libinterp/corefcn/oct-hdf5.h
+++ b/libinterp/corefcn/oct-hdf5.h
@@ -24,7 +24,11 @@
 #define octave_hdf5_h 1
 
 #if defined (HAVE_HDF5_H)
+
 #include <hdf5.h>
+
+#define HDF5_SAVE_TYPE H5T_NATIVE_UINT8
+
 #endif
 
 #endif
--- a/libinterp/octave-value/ov-base-int.cc
+++ b/libinterp/octave-value/ov-base-int.cc
@@ -38,6 +38,7 @@
 #include "gripes.h"
 #include "oct-obj.h"
 #include "oct-lvalue.h"
+#include "oct-hdf5.h"
 #include "oct-stream.h"
 #include "ops.h"
 #include "ov-base.h"
@@ -333,14 +334,15 @@
   return true;
 }
 
-#if defined (HAVE_HDF5)
-
 template <class T>
 bool
-octave_base_int_matrix<T>::save_hdf5 (hid_t loc_id, const char *name, bool)
+octave_base_int_matrix<T>::save_hdf5 (octave_hdf5_id loc_id, const char *name, bool)
 {
+  bool retval = false;
+
+#if defined (HAVE_HDF5)
+
   hid_t save_type_hid = HDF5_SAVE_TYPE;
-  bool retval = true;
   dim_vector dv = this->dims ();
   int empty = save_hdf5_empty (loc_id, name, dv);
   if (empty)
@@ -377,15 +379,22 @@
   H5Dclose (data_hid);
   H5Sclose (space_hid);
 
+#else
+  gripe_save ("hdf5");
+#endif
+
   return retval;
 }
 
 template <class T>
 bool
-octave_base_int_matrix<T>::load_hdf5 (hid_t loc_id, const char *name)
+octave_base_int_matrix<T>::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
+  bool retval = false;
+
+#if defined (HAVE_HDF5)
+
   hid_t save_type_hid = HDF5_SAVE_TYPE;
-  bool retval = false;
   dim_vector dv;
   int empty = load_hdf5_empty (loc_id, name, dv);
   if (empty > 0)
@@ -439,11 +448,13 @@
   H5Sclose (space_id);
   H5Dclose (data_hid);
 
+#else
+  gripe_load ("hdf5");
+#endif
+
   return retval;
 }
 
-#endif
-
 template <class T>
 void
 octave_base_int_matrix<T>::print_raw (std::ostream& os,
@@ -542,14 +553,15 @@
   return true;
 }
 
-#if defined (HAVE_HDF5)
-
 template <class T>
 bool
-octave_base_int_scalar<T>::save_hdf5 (hid_t loc_id, const char *name, bool)
+octave_base_int_scalar<T>::save_hdf5 (octave_hdf5_id loc_id, const char *name, bool)
 {
+  bool retval = false;
+
+#if defined (HAVE_HDF5)
+
   hid_t save_type_hid = HDF5_SAVE_TYPE;
-  bool retval = true;
   hsize_t dimens[3];
   hid_t space_hid, data_hid;
   space_hid = data_hid = -1;
@@ -576,13 +588,19 @@
   H5Dclose (data_hid);
   H5Sclose (space_hid);
 
+#else
+  gripe_save ("hdf5");
+#endif
+
   return retval;
 }
 
 template <class T>
 bool
-octave_base_int_scalar<T>::load_hdf5 (hid_t loc_id, const char *name)
+octave_base_int_scalar<T>::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
+#if defined (HAVE_HDF5)
+
   hid_t save_type_hid = HDF5_SAVE_TYPE;
 #if HAVE_HDF5_18
   hid_t data_hid = H5Dopen (loc_id, name, H5P_DEFAULT);
@@ -612,6 +630,10 @@
   H5Dclose (data_hid);
 
   return true;
+
+#else
+  gripe_load ("hdf5");
+  return false;
+#endif
 }
 
-#endif
--- a/libinterp/octave-value/ov-base-int.h
+++ b/libinterp/octave-value/ov-base-int.h
@@ -78,11 +78,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 };
 
 // base int scalar values.
@@ -123,11 +121,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 };
 
 #endif
--- a/libinterp/octave-value/ov-base.cc
+++ b/libinterp/octave-value/ov-base.cc
@@ -36,6 +36,7 @@
 #include "mxarray.h"
 #include "oct-map.h"
 #include "oct-obj.h"
+#include "oct-hdf5.h"
 #include "oct-lvalue.h"
 #include "oct-stream.h"
 #include "ops.h"
@@ -1090,10 +1091,8 @@
   return false;
 }
 
-#if defined (HAVE_HDF5)
-
 bool
-octave_base_value::save_hdf5 (hid_t, const char *, bool)
+octave_base_value::save_hdf5 (octave_hdf5_id, const char *, bool)
 {
   gripe_wrong_type_arg ("octave_base_value::save_binary()", type_name ());
 
@@ -1101,15 +1100,13 @@
 }
 
 bool
-octave_base_value::load_hdf5 (hid_t, const char *)
+octave_base_value::load_hdf5 (octave_hdf5_id, const char *)
 {
   gripe_wrong_type_arg ("octave_base_value::load_binary()", type_name ());
 
   return false;
 }
 
-#endif
-
 int
 octave_base_value::write (octave_stream&, int, oct_data_conv::data_type,
                           int, oct_mach_info::float_format) const
@@ -1257,6 +1254,24 @@
     return names[umap];
 }
 
+void
+octave_base_value::gripe_load (const char *type) const
+{
+  warning_with_id
+    ("Octave:load-save-unavailable",
+     "%s: loading %s files not available in this version of Octave",
+     t_name.c_str (), type);
+}
+
+void
+octave_base_value::gripe_save (const char *type) const
+{
+  warning_with_id
+    ("Octave:load-save-unavailable",
+     "%s: saving %s files not available in this version of Octave",
+     t_name.c_str (), type);
+}
+
 octave_value
 octave_base_value::map (unary_mapper_t umap) const
 {
--- a/libinterp/octave-value/ov-base.h
+++ b/libinterp/octave-value/ov-base.h
@@ -36,7 +36,7 @@
 #include "str-vec.h"
 
 #include "error.h"
-#include "oct-hdf5.h"
+#include "oct-hdf5-id.h"
 
 class Cell;
 class mxArray;
@@ -636,13 +636,11 @@
   virtual bool load_binary (std::istream& is, bool swap,
                             oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
   virtual bool
-  save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
   virtual bool
-  load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   virtual int
   write (octave_stream& os, int block_size,
@@ -821,6 +819,9 @@
 
   static const char *get_umap_name (unary_mapper_t);
 
+  void gripe_load (const char *type) const;
+  void gripe_save (const char *type) const;
+
 private:
 
   static int curr_print_indent_level;
--- a/libinterp/octave-value/ov-bool-mat.cc
+++ b/libinterp/octave-value/ov-bool-mat.cc
@@ -36,6 +36,7 @@
 #include "gripes.h"
 #include "mxarray.h"
 #include "oct-obj.h"
+#include "oct-hdf5.h"
 #include "ops.h"
 #include "ov-base.h"
 #include "ov-base-mat.h"
@@ -408,12 +409,14 @@
   return true;
 }
 
+bool
+octave_bool_matrix::save_hdf5 (octave_hdf5_id loc_id, const char *name,
+                               bool /* save_as_floats */)
+{
+  bool retval = true;
+
 #if defined (HAVE_HDF5)
 
-bool
-octave_bool_matrix::save_hdf5 (hid_t loc_id, const char *name,
-                               bool /* save_as_floats */)
-{
   dim_vector dv = dims ();
   int empty = save_hdf5_empty (loc_id, name, dv);
   if (empty)
@@ -422,7 +425,6 @@
   int rank = dv.length ();
   hid_t space_hid, data_hid;
   space_hid = data_hid = -1;
-  bool retval = true;
   boolNDArray m = bool_array_value ();
 
   OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
@@ -459,14 +461,20 @@
   H5Dclose (data_hid);
   H5Sclose (space_hid);
 
+#else
+  gripe_save ("hdf5");
+#endif
+
   return retval;
 }
 
 bool
-octave_bool_matrix::load_hdf5 (hid_t loc_id, const char *name)
+octave_bool_matrix::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
   bool retval = false;
 
+#if defined (HAVE_HDF5)
+
   dim_vector dv;
   int empty = load_hdf5_empty (loc_id, name, dv);
   if (empty > 0)
@@ -524,11 +532,13 @@
 
   H5Dclose (data_hid);
 
+#else
+  gripe_load ("hdf5");
+#endif
+
   return retval;
 }
 
-#endif
-
 mxArray *
 octave_bool_matrix::as_mxArray (void) const
 {
--- a/libinterp/octave-value/ov-bool-mat.h
+++ b/libinterp/octave-value/ov-bool-mat.h
@@ -205,11 +205,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   int write (octave_stream& os, int block_size,
              oct_data_conv::data_type output_type, int skip,
--- a/libinterp/octave-value/ov-bool-sparse.cc
+++ b/libinterp/octave-value/ov-bool-sparse.cc
@@ -40,6 +40,8 @@
 #include "ops.h"
 #include "oct-locbuf.h"
 
+#include "oct-hdf5.h"
+
 #include "ov-re-sparse.h"
 #include "ov-cx-sparse.h"
 #include "ov-bool-sparse.h"
@@ -336,11 +338,13 @@
   return true;
 }
 
+bool
+octave_sparse_bool_matrix::save_hdf5 (octave_hdf5_id loc_id, const char *name, bool)
+{
+  bool retval = false;
+
 #if defined (HAVE_HDF5)
 
-bool
-octave_sparse_bool_matrix::save_hdf5 (hid_t loc_id, const char *name, bool)
-{
   dim_vector dv = dims ();
   int empty = save_hdf5_empty (loc_id, name, dv);
   if (empty)
@@ -359,7 +363,6 @@
 
   hid_t space_hid, data_hid;
   space_hid = data_hid = -1;
-  bool retval = true;
   SparseBoolMatrix m = sparse_bool_matrix_value ();
   octave_idx_type tmp;
   hsize_t hdims[2];
@@ -545,12 +548,20 @@
   H5Sclose (space_hid);
   H5Gclose (group_hid);
 
+#else
+  gripe_save ("hdf5");
+#endif
+  
   return retval;
 }
 
 bool
-octave_sparse_bool_matrix::load_hdf5 (hid_t loc_id, const char *name)
+octave_sparse_bool_matrix::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
+  bool retval = false;
+
+#if defined (HAVE_HDF5)
+
   octave_idx_type nr, nc, nz;
   hid_t group_hid, data_hid, space_hid;
   hsize_t rank;
@@ -759,7 +770,7 @@
     }
 
   OCTAVE_LOCAL_BUFFER (hbool_t, htmp, nz);
-  bool retval = false;
+
   if (H5Dread (data_hid, H5T_NATIVE_HBOOL, H5S_ALL, H5S_ALL,
                H5P_DEFAULT, htmp) >= 0
       && m.indices_ok ())
@@ -776,11 +787,13 @@
   H5Dclose (data_hid);
   H5Gclose (group_hid);
 
+#else
+  gripe_load ("hdf5");
+#endif
+
   return retval;
 }
 
-#endif
-
 mxArray *
 octave_sparse_bool_matrix::as_mxArray (void) const
 {
--- a/libinterp/octave-value/ov-bool-sparse.h
+++ b/libinterp/octave-value/ov-bool-sparse.h
@@ -135,11 +135,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   mxArray *as_mxArray (void) const;
 
--- a/libinterp/octave-value/ov-bool.cc
+++ b/libinterp/octave-value/ov-bool.cc
@@ -30,6 +30,7 @@
 
 #include "gripes.h"
 #include "mxarray.h"
+#include "oct-hdf5.h"
 #include "oct-obj.h"
 #include "ops.h"
 #include "ov-bool.h"
@@ -157,16 +158,17 @@
   return true;
 }
 
+bool
+octave_bool::save_hdf5 (octave_hdf5_id loc_id, const char *name,
+                        bool /* save_as_floats */)
+{
+  bool retval = false;
+
 #if defined (HAVE_HDF5)
 
-bool
-octave_bool::save_hdf5 (hid_t loc_id, const char *name,
-                        bool /* save_as_floats */)
-{
   hsize_t dimens[3];
   hid_t space_hid, data_hid;
   space_hid = data_hid = -1;
-  bool retval = true;
 
   space_hid = H5Screate_simple (0, dimens, 0);
   if (space_hid < 0) return false;
@@ -190,12 +192,18 @@
   H5Dclose (data_hid);
   H5Sclose (space_hid);
 
+#else
+  gripe_save ("hdf5");
+#endif
+
   return retval;
 }
 
 bool
-octave_bool::load_hdf5 (hid_t loc_id, const char *name)
+octave_bool::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
+#if defined (HAVE_HDF5)
+
 #if HAVE_HDF5_18
   hid_t data_hid = H5Dopen (loc_id, name, H5P_DEFAULT);
 #else
@@ -223,11 +231,13 @@
 
   H5Dclose (data_hid);
 
+#else
+  gripe_load ("hdf5");
+#endif
+
   return true;
 }
 
-#endif
-
 mxArray *
 octave_bool::as_mxArray (void) const
 {
--- a/libinterp/octave-value/ov-bool.h
+++ b/libinterp/octave-value/ov-bool.h
@@ -218,11 +218,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   int write (octave_stream& os, int block_size,
              oct_data_conv::data_type output_type, int skip,
--- a/libinterp/octave-value/ov-cell.cc
+++ b/libinterp/octave-value/ov-cell.cc
@@ -42,6 +42,7 @@
 #include "mxarray.h"
 #include "ov-cell.h"
 #include "oct-obj.h"
+#include "oct-hdf5.h"
 #include "unwind-prot.h"
 #include "utils.h"
 #include "ov-base-mat.h"
@@ -1065,11 +1066,11 @@
   return matrix.mex_get_data ();
 }
 
+bool
+octave_cell::save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats)
+{
 #if defined (HAVE_HDF5)
 
-bool
-octave_cell::save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats)
-{
   dim_vector dv = dims ();
   int empty = save_hdf5_empty (loc_id, name, dv);
   if (empty)
@@ -1156,15 +1157,22 @@
   H5Gclose (data_hid);
 
   return true;
+
+#else
+  gripe_save ("hdf5");
+  return false;
+#endif
 }
 
 bool
-octave_cell::load_hdf5 (hid_t loc_id, const char *name)
+octave_cell::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
+  bool retval = false;
+
+#if defined (HAVE_HDF5)
+
   clear_cellstr_cache ();
 
-  bool retval = false;
-
   dim_vector dv;
   int empty = load_hdf5_empty (loc_id, name, dv);
   if (empty > 0)
@@ -1260,11 +1268,13 @@
       retval = true;
     }
 
+#else
+  gripe_load ("hdf5");
+#endif
+
   return retval;
 }
 
-#endif
-
 DEFUN (iscell, args, ,
        "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} iscell (@var{x})\n\
--- a/libinterp/octave-value/ov-cell.h
+++ b/libinterp/octave-value/ov-cell.h
@@ -161,11 +161,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   octave_value map (unary_mapper_t umap) const;
 
--- a/libinterp/octave-value/ov-class.cc
+++ b/libinterp/octave-value/ov-class.cc
@@ -44,6 +44,7 @@
 #include "ls-utils.h"
 #include "mxarray.h"
 #include "oct-lvalue.h"
+#include "oct-hdf5.h"
 #include "ov-class.h"
 #ifdef HAVE_JAVA
 #include "ov-java.h"
@@ -1505,11 +1506,11 @@
   return success;
 }
 
+bool
+octave_class::save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats)
+{
 #if defined (HAVE_HDF5)
 
-bool
-octave_class::save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats)
-{
   hsize_t hdims[3];
   hid_t group_hid = -1;
   hid_t type_hid = -1;
@@ -1601,13 +1602,20 @@
     H5Gclose (group_hid);
 
   return true;
+
+#else
+  gripe_save ("hdf5");
+  return false;
+#endif
 }
 
 bool
-octave_class::load_hdf5 (hid_t loc_id, const char *name)
+octave_class::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
   bool retval = false;
 
+#if defined (HAVE_HDF5)
+
   hid_t group_hid = -1;
   hid_t data_hid = -1;
   hid_t type_hid = -1;
@@ -1741,11 +1749,13 @@
   if (data_hid > 0)
     H5Gclose (group_hid);
 
+#else
+  gripe_load ("hdf5");
+#endif
+
   return retval;
 }
 
-#endif
-
 mxArray *
 octave_class::as_mxArray (void) const
 {
--- a/libinterp/octave-value/ov-class.h
+++ b/libinterp/octave-value/ov-class.h
@@ -194,11 +194,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   mxArray *as_mxArray (void) const;
 
--- a/libinterp/octave-value/ov-complex.cc
+++ b/libinterp/octave-value/ov-complex.cc
@@ -32,6 +32,7 @@
 
 #include "mxarray.h"
 #include "oct-obj.h"
+#include "oct-hdf5.h"
 #include "oct-stream.h"
 #include "ops.h"
 #include "ov-complex.h"
@@ -307,16 +308,17 @@
   return true;
 }
 
+bool
+octave_complex::save_hdf5 (octave_hdf5_id loc_id, const char *name,
+                           bool /* save_as_floats */)
+{
+  bool retval = false;
+
 #if defined (HAVE_HDF5)
 
-bool
-octave_complex::save_hdf5 (hid_t loc_id, const char *name,
-                           bool /* save_as_floats */)
-{
   hsize_t dimens[3];
   hid_t space_hid, type_hid, data_hid;
   space_hid = type_hid = data_hid = -1;
-  bool retval = true;
 
   space_hid = H5Screate_simple (0, dimens, 0);
   if (space_hid < 0)
@@ -349,13 +351,20 @@
   H5Tclose (type_hid);
   H5Sclose (space_hid);
 
+#else
+  gripe_save ("hdf5");
+#endif
+
   return retval;
 }
 
 bool
-octave_complex::load_hdf5 (hid_t loc_id, const char *name)
+octave_complex::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
   bool retval = false;
+
+#if defined (HAVE_HDF5)
+
 #if HAVE_HDF5_18
   hid_t data_hid = H5Dopen (loc_id, name, H5P_DEFAULT);
 #else
@@ -396,11 +405,13 @@
   H5Sclose (space_id);
   H5Dclose (data_hid);
 
+#else
+  gripe_load ("hdf5");
+#endif
+
   return retval;
 }
 
-#endif
-
 mxArray *
 octave_complex::as_mxArray (void) const
 {
--- a/libinterp/octave-value/ov-complex.h
+++ b/libinterp/octave-value/ov-complex.h
@@ -176,11 +176,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   int write (octave_stream& os, int block_size,
              oct_data_conv::data_type output_type, int skip,
--- a/libinterp/octave-value/ov-cx-mat.cc
+++ b/libinterp/octave-value/ov-cx-mat.cc
@@ -39,6 +39,7 @@
 #include "gripes.h"
 #include "mxarray.h"
 #include "oct-obj.h"
+#include "oct-hdf5.h"
 #include "oct-stream.h"
 #include "ops.h"
 #include "ov-base.h"
@@ -562,12 +563,12 @@
   return true;
 }
 
+bool
+octave_complex_matrix::save_hdf5 (octave_hdf5_id loc_id, const char *name,
+                                  bool save_as_floats)
+{
 #if defined (HAVE_HDF5)
 
-bool
-octave_complex_matrix::save_hdf5 (hid_t loc_id, const char *name,
-                                  bool save_as_floats)
-{
   dim_vector dv = dims ();
   int empty = save_hdf5_empty (loc_id, name, dv);
   if (empty)
@@ -651,13 +652,20 @@
   H5Sclose (space_hid);
 
   return retval;
+
+#else
+  gripe_save ("hdf5");
+  return false;
+#endif
 }
 
 bool
-octave_complex_matrix::load_hdf5 (hid_t loc_id, const char *name)
+octave_complex_matrix::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
   bool retval = false;
 
+#if defined (HAVE_HDF5)
+
   dim_vector dv;
   int empty = load_hdf5_empty (loc_id, name, dv);
   if (empty > 0)
@@ -725,11 +733,13 @@
   H5Sclose (space_id);
   H5Dclose (data_hid);
 
+#else
+  gripe_load ("hdf5");
+#endif
+
   return retval;
 }
 
-#endif
-
 void
 octave_complex_matrix::print_raw (std::ostream& os,
                                   bool pr_as_read_syntax) const
--- a/libinterp/octave-value/ov-cx-mat.h
+++ b/libinterp/octave-value/ov-cx-mat.h
@@ -155,11 +155,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   int write (octave_stream& os, int block_size,
              oct_data_conv::data_type output_type, int skip,
--- a/libinterp/octave-value/ov-cx-sparse.cc
+++ b/libinterp/octave-value/ov-cx-sparse.cc
@@ -39,6 +39,8 @@
 #include "ov-complex.h"
 #include "gripes.h"
 
+#include "oct-hdf5.h"
+
 #include "ov-re-sparse.h"
 #include "ov-cx-sparse.h"
 
@@ -366,12 +368,14 @@
   return true;
 }
 
+bool
+octave_sparse_complex_matrix::save_hdf5 (octave_hdf5_id loc_id, const char *name,
+                                         bool save_as_floats)
+{
+  bool retval = false;
+
 #if defined (HAVE_HDF5)
 
-bool
-octave_sparse_complex_matrix::save_hdf5 (hid_t loc_id, const char *name,
-                                         bool save_as_floats)
-{
   dim_vector dv = dims ();
   int empty = save_hdf5_empty (loc_id, name, dv);
   if (empty)
@@ -391,7 +395,6 @@
 
   hid_t space_hid, data_hid;
   space_hid = data_hid = -1;
-  bool retval = true;
   SparseComplexMatrix m = sparse_complex_matrix_value ();
   octave_idx_type tmp;
   hsize_t hdims[2];
@@ -614,12 +617,20 @@
   H5Tclose (type_hid);
   H5Gclose (group_hid);
 
+#else
+  gripe_save ("hdf5");
+#endif
+
   return retval;
 }
 
 bool
-octave_sparse_complex_matrix::load_hdf5 (hid_t loc_id, const char *name)
+octave_sparse_complex_matrix::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
+  bool retval = false;
+
+#if defined (HAVE_HDF5)
+
   octave_idx_type nr, nc, nz;
   hid_t group_hid, data_hid, space_hid;
   hsize_t rank;
@@ -840,7 +851,7 @@
     }
 
   Complex *ctmp = m.xdata ();
-  bool retval = false;
+
   if (H5Dread (data_hid, complex_type, H5S_ALL, H5S_ALL,
                H5P_DEFAULT, ctmp) >= 0
       && m.indices_ok ())
@@ -854,11 +865,13 @@
   H5Dclose (data_hid);
   H5Gclose (group_hid);
 
+#else
+  gripe_load ("hdf5");
+#endif
+
   return retval;
 }
 
-#endif
-
 mxArray *
 octave_sparse_complex_matrix::as_mxArray (void) const
 {
--- a/libinterp/octave-value/ov-cx-sparse.h
+++ b/libinterp/octave-value/ov-cx-sparse.h
@@ -141,11 +141,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   mxArray *as_mxArray (void) const;
 
--- a/libinterp/octave-value/ov-fcn-handle.cc
+++ b/libinterp/octave-value/ov-fcn-handle.cc
@@ -37,6 +37,7 @@
 #include "error.h"
 #include "gripes.h"
 #include "input.h"
+#include "oct-hdf5.h"
 #include "oct-map.h"
 #include "ov-base.h"
 #include "ov-fcn-handle.h"
@@ -704,11 +705,12 @@
   return success;
 }
 
-#if defined (HAVE_HDF5)
 bool
-octave_fcn_handle::save_hdf5 (hid_t loc_id, const char *name,
+octave_fcn_handle::save_hdf5 (octave_hdf5_id loc_id, const char *name,
                               bool save_as_floats)
 {
+#if defined (HAVE_HDF5)
+
   bool retval = true;
 
   hid_t group_hid = -1;
@@ -931,11 +933,18 @@
   H5Gclose (group_hid);
 
   return retval;
+
+#else
+  gripe_save ("hdf5");
+  return false;
+#endif
 }
 
 bool
-octave_fcn_handle::load_hdf5 (hid_t loc_id, const char *name)
+octave_fcn_handle::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
+#if defined (HAVE_HDF5)
+
   bool success = true;
 
   hid_t group_hid, data_hid, space_hid, type_hid, type_class_hid, st_id;
@@ -1291,10 +1300,13 @@
   H5Gclose (group_hid);
 
   return success;
+
+#else
+  gripe_load ("hdf5");
+  return false;
+#endif
 }
 
-#endif
-
 /*
 %!test
 %! a = 2;
--- a/libinterp/octave-value/ov-fcn-handle.h
+++ b/libinterp/octave-value/ov-fcn-handle.h
@@ -146,11 +146,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   void print (std::ostream& os, bool pr_as_read_syntax = false);
 
--- a/libinterp/octave-value/ov-fcn-inline.cc
+++ b/libinterp/octave-value/ov-fcn-inline.cc
@@ -38,6 +38,7 @@
 #include "defun.h"
 #include "error.h"
 #include "gripes.h"
+#include "oct-hdf5.h"
 #include "oct-map.h"
 #include "ov-base.h"
 #include "ov-fcn-inline.h"
@@ -272,12 +273,16 @@
   return true;
 }
 
-#if defined (HAVE_HDF5)
 bool
-octave_fcn_inline::save_hdf5 (hid_t loc_id, const char *name,
+octave_fcn_inline::save_hdf5 (octave_hdf5_id loc_id, const char *name,
                               bool /* save_as_floats */)
 {
+  bool retval = false;
+
+#if defined (HAVE_HDF5)
+
   hid_t group_hid = -1;
+
 #if HAVE_HDF5_18
   group_hid = H5Gcreate (loc_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
 #else
@@ -292,7 +297,6 @@
 
   hid_t space_hid, data_hid, type_hid;
   space_hid = data_hid = type_hid = -1;
-  bool retval = true;
 
   // FIXME: Is there a better way of saving string vectors,
   //        than a null padded matrix?
@@ -408,12 +412,18 @@
   H5Tclose (type_hid);
   H5Gclose (group_hid);
 
+#else
+  gripe_save ("hdf5");
+#endif
+
   return retval;
 }
 
 bool
-octave_fcn_inline::load_hdf5 (hid_t loc_id, const char *name)
+octave_fcn_inline::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
+#if defined (HAVE_HDF5)
+
   hid_t group_hid, data_hid, space_hid, type_hid, type_class_hid, st_id;
   hsize_t rank;
   int slen;
@@ -593,8 +603,12 @@
   fcn = ftmp.fcn;
 
   return true;
+
+#else
+  gripe_load ("hdf5");
+  return false;
+#endif
 }
-#endif
 
 void
 octave_fcn_inline::print (std::ostream& os, bool pr_as_read_syntax)
--- a/libinterp/octave-value/ov-fcn-inline.h
+++ b/libinterp/octave-value/ov-fcn-inline.h
@@ -79,11 +79,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   void print (std::ostream& os, bool pr_as_read_syntax = false);
 
--- a/libinterp/octave-value/ov-float.cc
+++ b/libinterp/octave-value/ov-float.cc
@@ -35,6 +35,7 @@
 #include "gripes.h"
 #include "mxarray.h"
 #include "oct-obj.h"
+#include "oct-hdf5.h"
 #include "oct-stream.h"
 #include "ov-scalar.h"
 #include "ov-float.h"
@@ -183,12 +184,12 @@
   return true;
 }
 
+bool
+octave_float_scalar::save_hdf5 (octave_hdf5_id loc_id, const char *name,
+                                bool /* save_as_floats */)
+{
 #if defined (HAVE_HDF5)
 
-bool
-octave_float_scalar::save_hdf5 (hid_t loc_id, const char *name,
-                                bool /* save_as_floats */)
-{
   hsize_t dimens[3];
   hid_t space_hid, data_hid;
   space_hid = data_hid = -1;
@@ -216,12 +217,18 @@
   H5Dclose (data_hid);
   H5Sclose (space_hid);
 
+#else
+  gripe_save ("hdf5");
+#endif
+
   return retval;
 }
 
 bool
-octave_float_scalar::load_hdf5 (hid_t loc_id, const char *name)
+octave_float_scalar::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
+#if defined (HAVE_HDF5)
+
 #if HAVE_HDF5_18
   hid_t data_hid = H5Dopen (loc_id, name, H5P_DEFAULT);
 #else
@@ -250,10 +257,13 @@
   H5Dclose (data_hid);
 
   return true;
+
+#else
+  gripe_load ("hdf5");
+  return false;
+#endif
 }
 
-#endif
-
 mxArray *
 octave_float_scalar::as_mxArray (void) const
 {
--- a/libinterp/octave-value/ov-float.h
+++ b/libinterp/octave-value/ov-float.h
@@ -231,11 +231,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   int write (octave_stream& os, int block_size,
              oct_data_conv::data_type output_type, int skip,
--- a/libinterp/octave-value/ov-flt-complex.cc
+++ b/libinterp/octave-value/ov-flt-complex.cc
@@ -32,6 +32,7 @@
 
 #include "mxarray.h"
 #include "oct-obj.h"
+#include "oct-hdf5.h"
 #include "oct-stream.h"
 #include "ops.h"
 #include "ov-complex.h"
@@ -293,16 +294,17 @@
   return true;
 }
 
+bool
+octave_float_complex::save_hdf5 (octave_hdf5_id loc_id, const char *name,
+                                 bool /* save_as_floats */)
+{
+  bool retval = false;
+
 #if defined (HAVE_HDF5)
 
-bool
-octave_float_complex::save_hdf5 (hid_t loc_id, const char *name,
-                                 bool /* save_as_floats */)
-{
   hsize_t dimens[3];
   hid_t space_hid, type_hid, data_hid;
   space_hid = type_hid = data_hid = -1;
-  bool retval = true;
 
   space_hid = H5Screate_simple (0, dimens, 0);
   if (space_hid < 0)
@@ -335,13 +337,20 @@
   H5Tclose (type_hid);
   H5Sclose (space_hid);
 
+#else
+  gripe_save ("hdf5");
+#endif
+
   return retval;
 }
 
 bool
-octave_float_complex::load_hdf5 (hid_t loc_id, const char *name)
+octave_float_complex::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
   bool retval = false;
+
+#if defined (HAVE_HDF5)
+
 #if HAVE_HDF5_18
   hid_t data_hid = H5Dopen (loc_id, name, H5P_DEFAULT);
 #else
@@ -382,11 +391,13 @@
   H5Sclose (space_id);
   H5Dclose (data_hid);
 
+#else
+  gripe_load ("hdf5");
+#endif
+
   return retval;
 }
 
-#endif
-
 mxArray *
 octave_float_complex::as_mxArray (void) const
 {
--- a/libinterp/octave-value/ov-flt-complex.h
+++ b/libinterp/octave-value/ov-flt-complex.h
@@ -167,11 +167,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   int write (octave_stream& os, int block_size,
              oct_data_conv::data_type output_type, int skip,
--- a/libinterp/octave-value/ov-flt-cx-mat.cc
+++ b/libinterp/octave-value/ov-flt-cx-mat.cc
@@ -39,6 +39,7 @@
 #include "gripes.h"
 #include "mxarray.h"
 #include "oct-obj.h"
+#include "oct-hdf5.h"
 #include "oct-stream.h"
 #include "ops.h"
 #include "ov-base.h"
@@ -524,11 +525,13 @@
   return true;
 }
 
+bool
+octave_float_complex_matrix::save_hdf5 (octave_hdf5_id loc_id, const char *name, bool)
+{
+  bool retval = false;
+
 #if defined (HAVE_HDF5)
 
-bool
-octave_float_complex_matrix::save_hdf5 (hid_t loc_id, const char *name, bool)
-{
   dim_vector dv = dims ();
   int empty = save_hdf5_empty (loc_id, name, dv);
   if (empty)
@@ -537,7 +540,6 @@
   int rank = dv.length ();
   hid_t space_hid, data_hid, type_hid;
   space_hid = data_hid = type_hid = -1;
-  bool retval = true;
   FloatComplexNDArray m = complex_array_value ();
 
   OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
@@ -601,14 +603,20 @@
   H5Tclose (type_hid);
   H5Sclose (space_hid);
 
+#else
+  gripe_save ("hdf5");
+#endif
+
   return retval;
 }
 
 bool
-octave_float_complex_matrix::load_hdf5 (hid_t loc_id, const char *name)
+octave_float_complex_matrix::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
   bool retval = false;
 
+#if defined (HAVE_HDF5)
+
   dim_vector dv;
   int empty = load_hdf5_empty (loc_id, name, dv);
   if (empty > 0)
@@ -676,11 +684,13 @@
   H5Sclose (space_id);
   H5Dclose (data_hid);
 
+#else
+  gripe_load ("hdf5");
+#endif
+
   return retval;
 }
 
-#endif
-
 void
 octave_float_complex_matrix::print_raw (std::ostream& os,
                                         bool pr_as_read_syntax) const
--- a/libinterp/octave-value/ov-flt-cx-mat.h
+++ b/libinterp/octave-value/ov-flt-cx-mat.h
@@ -151,11 +151,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   int write (octave_stream& os, int block_size,
              oct_data_conv::data_type output_type, int skip,
--- a/libinterp/octave-value/ov-flt-re-mat.cc
+++ b/libinterp/octave-value/ov-flt-re-mat.cc
@@ -44,6 +44,7 @@
 #include "mxarray.h"
 #include "oct-obj.h"
 #include "oct-lvalue.h"
+#include "oct-hdf5.h"
 #include "oct-stream.h"
 #include "ops.h"
 #include "ov-base.h"
@@ -551,11 +552,13 @@
   return true;
 }
 
+bool
+octave_float_matrix::save_hdf5 (octave_hdf5_id loc_id, const char *name, bool)
+{
+  bool retval = false;
+
 #if defined (HAVE_HDF5)
 
-bool
-octave_float_matrix::save_hdf5 (hid_t loc_id, const char *name, bool)
-{
   dim_vector dv = dims ();
   int empty = save_hdf5_empty (loc_id, name, dv);
   if (empty)
@@ -564,7 +567,6 @@
   int rank = dv.length ();
   hid_t space_hid, data_hid;
   space_hid = data_hid = -1;
-  bool retval = true;
   FloatNDArray m = array_value ();
 
   OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
@@ -610,14 +612,20 @@
   H5Dclose (data_hid);
   H5Sclose (space_hid);
 
+#else
+  gripe_save ("hdf5");
+#endif
+
   return retval;
 }
 
 bool
-octave_float_matrix::load_hdf5 (hid_t loc_id, const char *name)
+octave_float_matrix::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
   bool retval = false;
 
+#if defined (HAVE_HDF5)
+
   dim_vector dv;
   int empty = load_hdf5_empty (loc_id, name, dv);
   if (empty > 0)
@@ -672,11 +680,13 @@
   H5Sclose (space_id);
   H5Dclose (data_hid);
 
+#else
+  gripe_load ("hdf5");
+#endif
+
   return retval;
 }
 
-#endif
-
 void
 octave_float_matrix::print_raw (std::ostream& os,
                                 bool pr_as_read_syntax) const
--- a/libinterp/octave-value/ov-flt-re-mat.h
+++ b/libinterp/octave-value/ov-flt-re-mat.h
@@ -189,11 +189,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   int write (octave_stream& os, int block_size,
              oct_data_conv::data_type output_type, int skip,
--- a/libinterp/octave-value/ov-int16.cc
+++ b/libinterp/octave-value/ov-int16.cc
@@ -36,13 +36,10 @@
 #include "gripes.h"
 #include "oct-obj.h"
 #include "oct-lvalue.h"
+#include "oct-hdf5.h"
 #include "ops.h"
 #include "ov-base.h"
 
-#ifdef HAVE_HDF5
-#define HDF5_SAVE_TYPE H5T_NATIVE_INT16
-#endif
-
 #include "ov-base-int.h"
 #include "ov-base-int.cc"
 #include "ov-int16.h"
--- a/libinterp/octave-value/ov-int32.cc
+++ b/libinterp/octave-value/ov-int32.cc
@@ -36,13 +36,10 @@
 #include "gripes.h"
 #include "oct-obj.h"
 #include "oct-lvalue.h"
+#include "oct-hdf5.h"
 #include "ops.h"
 #include "ov-base.h"
 
-#ifdef HAVE_HDF5
-#define HDF5_SAVE_TYPE H5T_NATIVE_INT32
-#endif
-
 #include "ov-base-int.h"
 #include "ov-base-int.cc"
 #include "ov-int32.h"
--- a/libinterp/octave-value/ov-int64.cc
+++ b/libinterp/octave-value/ov-int64.cc
@@ -36,13 +36,10 @@
 #include "gripes.h"
 #include "oct-obj.h"
 #include "oct-lvalue.h"
+#include "oct-hdf5.h"
 #include "ops.h"
 #include "ov-base.h"
 
-#ifdef HAVE_HDF5
-#define HDF5_SAVE_TYPE H5T_NATIVE_INT64
-#endif
-
 #include "ov-base-int.h"
 #include "ov-base-int.cc"
 #include "ov-int64.h"
--- a/libinterp/octave-value/ov-int8.cc
+++ b/libinterp/octave-value/ov-int8.cc
@@ -36,13 +36,10 @@
 #include "gripes.h"
 #include "oct-obj.h"
 #include "oct-lvalue.h"
+#include "oct-hdf5.h"
 #include "ops.h"
 #include "ov-base.h"
 
-#ifdef HAVE_HDF5
-#define HDF5_SAVE_TYPE H5T_NATIVE_INT8
-#endif
-
 #include "ov-base-int.h"
 #include "ov-base-int.cc"
 #include "ov-int8.h"
--- a/libinterp/octave-value/ov-lazy-idx.h
+++ b/libinterp/octave-value/ov-lazy-idx.h
@@ -203,7 +203,6 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-  // HDF5 functions not defined.
 
   int write (octave_stream& os, int block_size,
              oct_data_conv::data_type output_type, int skip,
@@ -248,4 +247,3 @@
 };
 
 #endif
-
--- a/libinterp/octave-value/ov-oncleanup.cc
+++ b/libinterp/octave-value/ov-oncleanup.cc
@@ -147,9 +147,9 @@
   return true;
 }
 
-#if defined (HAVE_HDF5)
 bool
-octave_oncleanup::save_hdf5 (hid_t /* loc_id */, const char * /* name */,
+octave_oncleanup::save_hdf5 (octave_hdf5_id /* loc_id */,
+                             const char * /* name */,
                              bool /* save_as_floats */)
 {
   warn_save_load ();
@@ -157,12 +157,12 @@
 }
 
 bool
-octave_oncleanup::load_hdf5 (hid_t /* loc_id */, const char * /* name */)
+octave_oncleanup::load_hdf5 (octave_hdf5_id /* loc_id */,
+                             const char * /* name */)
 {
   warn_save_load ();
   return true;
 }
-#endif
 
 void
 octave_oncleanup::print (std::ostream& os, bool pr_as_read_syntax)
--- a/libinterp/octave-value/ov-oncleanup.h
+++ b/libinterp/octave-value/ov-oncleanup.h
@@ -81,11 +81,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   void print (std::ostream& os, bool pr_as_read_syntax = false);
 
--- a/libinterp/octave-value/ov-range.cc
+++ b/libinterp/octave-value/ov-range.cc
@@ -35,6 +35,7 @@
 #include "mxarray.h"
 #include "ops.h"
 #include "oct-obj.h"
+#include "oct-hdf5.h"
 #include "ov-range.h"
 #include "ov-re-mat.h"
 #include "ov-scalar.h"
@@ -543,14 +544,19 @@
   return type_id;
 }
 
+#endif
+
 bool
-octave_range::save_hdf5 (hid_t loc_id, const char *name,
+octave_range::save_hdf5 (octave_hdf5_id loc_id, const char *name,
                          bool /* save_as_floats */)
 {
+  bool retval = false;
+
+#if defined (HAVE_HDF5)
+
   hsize_t dimens[3];
   hid_t space_hid, type_hid, data_hid;
   space_hid = type_hid = data_hid = -1;
-  bool retval = true;
 
   space_hid = H5Screate_simple (0, dimens, 0);
   if (space_hid < 0) return false;
@@ -594,14 +600,20 @@
   H5Tclose (type_hid);
   H5Sclose (space_hid);
 
+#else
+  gripe_save ("hdf5");
+#endif
+
   return retval;
 }
 
 bool
-octave_range::load_hdf5 (hid_t loc_id, const char *name)
+octave_range::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
   bool retval = false;
 
+#if defined (HAVE_HDF5)
+
 #if HAVE_HDF5_18
   hid_t data_hid = H5Dopen (loc_id, name, H5P_DEFAULT);
 #else
@@ -652,11 +664,13 @@
   H5Sclose (space_hid);
   H5Dclose (data_hid);
 
+#else
+  gripe_load ("hdf5");
+#endif
+
   return retval;
 }
 
-#endif
-
 mxArray *
 octave_range::as_mxArray (void) const
 {
--- a/libinterp/octave-value/ov-range.h
+++ b/libinterp/octave-value/ov-range.h
@@ -265,11 +265,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   int write (octave_stream& os, int block_size,
              oct_data_conv::data_type output_type, int skip,
--- a/libinterp/octave-value/ov-re-mat.cc
+++ b/libinterp/octave-value/ov-re-mat.cc
@@ -44,6 +44,7 @@
 #include "mxarray.h"
 #include "oct-obj.h"
 #include "oct-lvalue.h"
+#include "oct-hdf5.h"
 #include "oct-stream.h"
 #include "ops.h"
 #include "ov-base.h"
@@ -663,11 +664,13 @@
   return true;
 }
 
+bool
+octave_matrix::save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats)
+{
+  bool retval = false;
+
 #if defined (HAVE_HDF5)
 
-bool
-octave_matrix::save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats)
-{
   dim_vector dv = dims ();
   int empty = save_hdf5_empty (loc_id, name, dv);
   if (empty)
@@ -676,7 +679,6 @@
   int rank = dv.length ();
   hid_t space_hid, data_hid;
   space_hid = data_hid = -1;
-  bool retval = true;
   NDArray m = array_value ();
 
   OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
@@ -733,14 +735,20 @@
   H5Dclose (data_hid);
   H5Sclose (space_hid);
 
+#else
+  gripe_save ("hdf5");
+#endif
+
   return retval;
 }
 
 bool
-octave_matrix::load_hdf5 (hid_t loc_id, const char *name)
+octave_matrix::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
   bool retval = false;
 
+#if defined (HAVE_HDF5)
+
   dim_vector dv;
   int empty = load_hdf5_empty (loc_id, name, dv);
   if (empty > 0)
@@ -795,11 +803,13 @@
   H5Sclose (space_id);
   H5Dclose (data_hid);
 
+#else
+  gripe_load ("hdf5");
+#endif
+
   return retval;
 }
 
-#endif
-
 void
 octave_matrix::print_raw (std::ostream& os,
                           bool pr_as_read_syntax) const
--- a/libinterp/octave-value/ov-re-mat.h
+++ b/libinterp/octave-value/ov-re-mat.h
@@ -213,11 +213,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   int write (octave_stream& os, int block_size,
              oct_data_conv::data_type output_type, int skip,
--- a/libinterp/octave-value/ov-re-sparse.cc
+++ b/libinterp/octave-value/ov-re-sparse.cc
@@ -38,6 +38,7 @@
 #include "ov-scalar.h"
 #include "gripes.h"
 
+#include "oct-hdf5.h"
 #include "ls-hdf5.h"
 
 #include "ov-re-sparse.h"
@@ -397,12 +398,14 @@
   return true;
 }
 
+bool
+octave_sparse_matrix::save_hdf5 (octave_hdf5_id loc_id, const char *name,
+                                 bool save_as_floats)
+{
+  bool retval = false;
+
 #if defined (HAVE_HDF5)
 
-bool
-octave_sparse_matrix::save_hdf5 (hid_t loc_id, const char *name,
-                                 bool save_as_floats)
-{
   dim_vector dv = dims ();
   int empty = save_hdf5_empty (loc_id, name, dv);
   if (empty)
@@ -422,7 +425,6 @@
 
   hid_t space_hid, data_hid;
   space_hid = data_hid = -1;
-  bool retval = true;
   SparseMatrix m = sparse_matrix_value ();
   octave_idx_type tmp;
   hsize_t hdims[2];
@@ -627,12 +629,20 @@
   H5Sclose (space_hid);
   H5Gclose (group_hid);
 
+#else
+  gripe_save ("hdf5");
+#endif
+
   return retval;
 }
 
 bool
-octave_sparse_matrix::load_hdf5 (hid_t loc_id, const char *name)
+octave_sparse_matrix::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
+  bool retval = false;
+
+#if defined (HAVE_HDF5)
+
   octave_idx_type nr, nc, nz;
   hid_t group_hid, data_hid, space_hid;
   hsize_t rank;
@@ -839,7 +849,7 @@
     }
 
   double *dtmp = m.xdata ();
-  bool retval = false;
+
   if (H5Dread (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
                H5P_DEFAULT, dtmp) >= 0
       && m.indices_ok ())
@@ -852,11 +862,13 @@
   H5Dclose (data_hid);
   H5Gclose (group_hid);
 
+#else
+  gripe_load ("hdf5");
+#endif
+  
   return retval;
 }
 
-#endif
-
 mxArray *
 octave_sparse_matrix::as_mxArray (void) const
 {
--- a/libinterp/octave-value/ov-re-sparse.h
+++ b/libinterp/octave-value/ov-re-sparse.h
@@ -144,11 +144,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   mxArray *as_mxArray (void) const;
 
--- a/libinterp/octave-value/ov-scalar.cc
+++ b/libinterp/octave-value/ov-scalar.cc
@@ -35,6 +35,7 @@
 #include "gripes.h"
 #include "mxarray.h"
 #include "oct-obj.h"
+#include "oct-hdf5.h"
 #include "oct-stream.h"
 #include "ov-scalar.h"
 #include "ov-float.h"
@@ -198,16 +199,17 @@
   return true;
 }
 
+bool
+octave_scalar::save_hdf5 (octave_hdf5_id loc_id, const char *name,
+                          bool /* save_as_floats */)
+{
+  bool retval = false;
+
 #if defined (HAVE_HDF5)
 
-bool
-octave_scalar::save_hdf5 (hid_t loc_id, const char *name,
-                          bool /* save_as_floats */)
-{
   hsize_t dimens[3];
   hid_t space_hid, data_hid;
   space_hid = data_hid = -1;
-  bool retval = true;
 
   space_hid = H5Screate_simple (0, dimens, 0);
   if (space_hid < 0) return false;
@@ -232,12 +234,18 @@
   H5Dclose (data_hid);
   H5Sclose (space_hid);
 
+#else
+  gripe_save ("hdf5");
+#endif
+
   return retval;
 }
 
 bool
-octave_scalar::load_hdf5 (hid_t loc_id, const char *name)
+octave_scalar::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
+#if defined (HAVE_HDF5)
+
 #if HAVE_HDF5_18
   hid_t data_hid = H5Dopen (loc_id, name, H5P_DEFAULT);
 #else
@@ -266,10 +274,13 @@
   H5Dclose (data_hid);
 
   return true;
+
+#else
+  gripe_load ("hdf5");
+  return false;
+#endif
 }
 
-#endif
-
 mxArray *
 octave_scalar::as_mxArray (void) const
 {
--- a/libinterp/octave-value/ov-scalar.h
+++ b/libinterp/octave-value/ov-scalar.h
@@ -230,11 +230,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   int write (octave_stream& os, int block_size,
              oct_data_conv::data_type output_type, int skip,
--- a/libinterp/octave-value/ov-str-mat.cc
+++ b/libinterp/octave-value/ov-str-mat.cc
@@ -44,6 +44,7 @@
 #include "ls-oct-ascii.h"
 #include "ls-utils.h"
 #include "oct-obj.h"
+#include "oct-hdf5.h"
 #include "oct-stream.h"
 #include "ops.h"
 #include "ov-scalar.h"
@@ -569,12 +570,14 @@
   return true;
 }
 
+bool
+octave_char_matrix_str::save_hdf5 (octave_hdf5_id loc_id, const char *name,
+                                   bool /* save_as_floats */)
+{
+  bool retval = false;
+
 #if defined (HAVE_HDF5)
 
-bool
-octave_char_matrix_str::save_hdf5 (hid_t loc_id, const char *name,
-                                   bool /* save_as_floats */)
-{
   dim_vector dv = dims ();
   int empty = save_hdf5_empty (loc_id, name, dv);
   if (empty)
@@ -583,7 +586,6 @@
   int rank = dv.length ();
   hid_t space_hid, data_hid;
   space_hid = data_hid = -1;
-  bool retval = true;
   charNDArray m = char_array_value ();
 
   OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
@@ -619,14 +621,20 @@
   H5Dclose (data_hid);
   H5Sclose (space_hid);
 
+#else
+  gripe_save ("hdf5");
+#endif
+
   return retval;
 }
 
 bool
-octave_char_matrix_str::load_hdf5 (hid_t loc_id, const char *name)
+octave_char_matrix_str::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
   bool retval = false;
 
+#if defined (HAVE_HDF5)
+
   dim_vector dv;
   int empty = load_hdf5_empty (loc_id, name, dv);
   if (empty > 0)
@@ -788,7 +796,9 @@
         }
     }
 
+#else
+  gripe_load ("hdf5");
+#endif
+
   return retval;
 }
-
-#endif
--- a/libinterp/octave-value/ov-str-mat.h
+++ b/libinterp/octave-value/ov-str-mat.h
@@ -153,11 +153,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   int write (octave_stream& os, int block_size,
              oct_data_conv::data_type output_type, int skip,
--- a/libinterp/octave-value/ov-struct.cc
+++ b/libinterp/octave-value/ov-struct.cc
@@ -32,6 +32,7 @@
 #include "gripes.h"
 #include "mxarray.h"
 #include "oct-lvalue.h"
+#include "oct-hdf5.h"
 #include "ov-struct.h"
 #include "unwind-prot.h"
 #include "utils.h"
@@ -979,11 +980,11 @@
   return success;
 }
 
+bool
+octave_struct::save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats)
+{
 #if defined (HAVE_HDF5)
 
-bool
-octave_struct::save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats)
-{
   hid_t data_hid = -1;
 
 #if HAVE_HDF5_18
@@ -1018,13 +1019,20 @@
   H5Gclose (data_hid);
 
   return true;
+
+#else
+  gripe_save ("hdf5");
+  return false;
+#endif
 }
 
 bool
-octave_struct::load_hdf5 (hid_t loc_id, const char *name)
+octave_struct::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
   bool retval = false;
 
+#if defined (HAVE_HDF5)
+
   hdf5_callback_data dsub;
 
   herr_t retval2 = 0;
@@ -1066,11 +1074,13 @@
       retval = true;
     }
 
+#else
+  gripe_load ("hdf5");
+#endif
+
   return retval;
 }
 
-#endif
-
 mxArray *
 octave_struct::as_mxArray (void) const
 {
@@ -1614,12 +1624,12 @@
   return success;
 }
 
-#if defined (HAVE_HDF5)
-
 bool
-octave_scalar_struct::save_hdf5 (hid_t loc_id, const char *name,
+octave_scalar_struct::save_hdf5 (octave_hdf5_id loc_id, const char *name,
                                  bool save_as_floats)
 {
+#if defined (HAVE_HDF5)
+
   hid_t data_hid = -1;
 
 #if HAVE_HDF5_18
@@ -1654,13 +1664,20 @@
   H5Gclose (data_hid);
 
   return true;
+
+#else
+  gripe_save ("hdf5");
+  return false;
+#endif
 }
 
 bool
-octave_scalar_struct::load_hdf5 (hid_t loc_id, const char *name)
+octave_scalar_struct::load_hdf5 (octave_hdf5_id loc_id, const char *name)
 {
   bool retval = false;
 
+#if defined (HAVE_HDF5)
+
   hdf5_callback_data dsub;
 
   herr_t retval2 = 0;
@@ -1700,11 +1717,13 @@
       retval = true;
     }
 
+#else
+  gripe_load ("hdf5");
+#endif
+
   return retval;
 }
 
-#endif
-
 mxArray *
 octave_scalar_struct::as_mxArray (void) const
 {
--- a/libinterp/octave-value/ov-struct.h
+++ b/libinterp/octave-value/ov-struct.h
@@ -140,11 +140,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   mxArray *as_mxArray (void) const;
 
@@ -262,11 +260,9 @@
   bool load_binary (std::istream& is, bool swap,
                     oct_mach_info::float_format fmt);
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats);
 
-  bool load_hdf5 (hid_t loc_id, const char *name);
-#endif
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name);
 
   mxArray *as_mxArray (void) const;
 
--- a/libinterp/octave-value/ov-uint16.cc
+++ b/libinterp/octave-value/ov-uint16.cc
@@ -36,13 +36,10 @@
 #include "gripes.h"
 #include "oct-obj.h"
 #include "oct-lvalue.h"
+#include "oct-hdf5.h"
 #include "ops.h"
 #include "ov-base.h"
 
-#ifdef HAVE_HDF5
-#define HDF5_SAVE_TYPE H5T_NATIVE_UINT16
-#endif
-
 #include "ov-base-int.h"
 #include "ov-base-int.cc"
 #include "ov-uint16.h"
--- a/libinterp/octave-value/ov-uint32.cc
+++ b/libinterp/octave-value/ov-uint32.cc
@@ -36,13 +36,10 @@
 #include "gripes.h"
 #include "oct-obj.h"
 #include "oct-lvalue.h"
+#include "oct-hdf5.h"
 #include "ops.h"
 #include "ov-base.h"
 
-#ifdef HAVE_HDF5
-#define HDF5_SAVE_TYPE H5T_NATIVE_UINT32
-#endif
-
 #include "ov-base-int.h"
 #include "ov-base-int.cc"
 #include "ov-uint32.h"
--- a/libinterp/octave-value/ov-uint64.cc
+++ b/libinterp/octave-value/ov-uint64.cc
@@ -36,13 +36,10 @@
 #include "gripes.h"
 #include "oct-obj.h"
 #include "oct-lvalue.h"
+#include "oct-hdf5.h"
 #include "ops.h"
 #include "ov-base.h"
 
-#ifdef HAVE_HDF5
-#define HDF5_SAVE_TYPE H5T_NATIVE_UINT64
-#endif
-
 #include "ov-base-int.h"
 #include "ov-base-int.cc"
 #include "ov-uint64.h"
--- a/libinterp/octave-value/ov-uint8.cc
+++ b/libinterp/octave-value/ov-uint8.cc
@@ -36,13 +36,10 @@
 #include "gripes.h"
 #include "oct-obj.h"
 #include "oct-lvalue.h"
+#include "oct-hdf5.h"
 #include "ops.h"
 #include "ov-base.h"
 
-#ifdef HAVE_HDF5
-#define HDF5_SAVE_TYPE H5T_NATIVE_UINT8
-#endif
-
 #include "ov-base-int.h"
 #include "ov-base-int.cc"
 #include "ov-uint8.h"
--- a/libinterp/octave-value/ov.h
+++ b/libinterp/octave-value/ov.h
@@ -38,7 +38,6 @@
 #include "oct-time.h"
 #include "str-vec.h"
 
-#include "oct-hdf5.h"
 #include "oct-sort.h"
 
 class Cell;
@@ -57,8 +56,6 @@
 
 // Constants.
 
-class octave_value;
-
 class
 OCTINTERP_API
 octave_value
@@ -1094,13 +1091,12 @@
                     oct_mach_info::float_format fmt)
   { return rep->load_binary (is, swap, fmt); }
 
-#if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats)
+  bool save_hdf5 (octave_hdf5_id loc_id, const char *name,
+                  bool save_as_floats)
   { return rep->save_hdf5 (loc_id, name, save_as_floats); }
 
-  bool load_hdf5 (hid_t loc_id, const char *name)
+  bool load_hdf5 (octave_hdf5_id loc_id, const char *name)
   { return rep->load_hdf5 (loc_id, name); }
-#endif
 
   int write (octave_stream& os, int block_size,
              oct_data_conv::data_type output_type, int skip,