changeset 10349:d4d13389c957

make load-save to matlab format work when using --enable-64
author John W. Eaton <jwe@octave.org>
date Mon, 22 Feb 2010 23:07:21 -0500
parents df1df5f0c236
children 12884915a8e4
files liboctave/ChangeLog liboctave/data-conv.cc liboctave/data-conv.h src/ChangeLog src/ls-mat5.cc
diffstat 5 files changed, 432 insertions(+), 275 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/ChangeLog
+++ b/liboctave/ChangeLog
@@ -1,3 +1,38 @@
+2010-02-22  John W. Eaton  <jwe@octave.org>
+
+	* data-conv.cc, data-conv.h (read_floats, read_doubles,
+	do_float_format_conversion, do_double_format_conversion):
+	Declare len arg and loop counter as octave_idx_type, not int.
+	(strip_spaces): Use size_t for string dimension and index, not int.
+	(LS_DO_READ, LS_DO_WRITE): Declare loop counter as
+	octave_idx_type, not int.
+	(write_floats, write_doubles):
+	Declare len arg as octave_idx_type, not int.
+	(IEEE_big_double_to_IEEE_little_double,
+	VAX_D_double_to_IEEE_little_double,
+	VAX_G_double_to_IEEE_little_double,
+	Cray_to_IEEE_little_double,
+	IEEE_big_float_to_IEEE_little_float,
+	VAX_D_float_to_IEEE_little_float,
+	VAX_G_float_to_IEEE_little_float, Cray_to_IEEE_little_float,
+	IEEE_little_double_to_IEEE_big_double,
+	VAX_D_double_to_IEEE_big_double,
+	VAX_G_double_to_IEEE_big_double, Cray_to_IEEE_big_double,
+	IEEE_little_float_to_IEEE_big_float,
+	VAX_D_float_to_IEEE_big_float, VAX_G_float_to_IEEE_big_float,
+	Cray_to_IEEE_big_float, IEEE_little_double_to_VAX_D_double,
+	IEEE_big_double_to_VAX_D_double,
+	VAX_G_double_to_VAX_D_double, Cray_to_VAX_D_double,
+	IEEE_little_float_to_VAX_D_float,
+	IEEE_big_float_to_VAX_D_float, VAX_G_float_to_VAX_D_float,
+	Cray_to_VAX_D_float, IEEE_little_double_to_VAX_G_double,
+	IEEE_big_double_to_VAX_G_double,
+	VAX_D_double_to_VAX_G_double, Cray_to_VAX_G_double,
+	IEEE_little_float_to_VAX_G_float,
+	IEEE_big_float_to_VAX_G_float, VAX_D_float_to_VAX_G_float,
+	Cray_to_VAX_G_float, read_doubles):
+	Declare len arg as octave_idx_type, not int.
+
 2010-02-21  Michael Goffioul  <michael.goffioul@gmail.com>
 
 	* lo-sysdep.cc, lo-utils.h, oct-shlib.h: Define WIN32_LEAN_AND_MEAN
--- a/liboctave/data-conv.cc
+++ b/liboctave/data-conv.cc
@@ -134,13 +134,13 @@
 static std::string
 strip_spaces (const std::string& str)
 {
-  int n = str.length ();
+  size_t n = str.length ();
 
-  int k = 0;
+  size_t k = 0;
 
   std::string s (n, ' ');
 
-  for (int i = 0; i < n; i++)
+  for (size_t i = 0; i < n; i++)
     if (! isspace (str[i]))
       s[k++] = tolower (str[i]);
 
@@ -490,7 +490,7 @@
           stream.read (reinterpret_cast<char *>  (ptr), size * len); \
           if (swap) \
             swap_bytes< size > (ptr, len); \
-          for (int i = 0; i < len; i++) \
+          for (octave_idx_type i = 0; i < len; i++) \
             data[i] = ptr[i]; \
         } \
     } \
@@ -507,7 +507,7 @@
           char tmp_type = type; \
           stream.write (&tmp_type, 1); \
           OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
-          for (int i = 0; i < len; i++) \
+          for (octave_idx_type i = 0; i < len; i++) \
             ptr[i] = static_cast <TYPE> (data[i]);         \
           stream.write (reinterpret_cast<char *> (ptr), size * len); \
         } \
@@ -540,199 +540,199 @@
 // FIXME -- assumes sizeof (float) == 4
 
 static void
-IEEE_big_double_to_IEEE_little_double (void *d, int len)
+IEEE_big_double_to_IEEE_little_double (void *d, octave_idx_type len)
 {
   swap_bytes<8> (d, len);
 }
 
 static void
-VAX_D_double_to_IEEE_little_double (void * /* d */, int /* len */)
+VAX_D_double_to_IEEE_little_double (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("VAX D float", "IEEE little endian format");
 }
 
 static void
-VAX_G_double_to_IEEE_little_double (void * /* d */, int /* len */)
+VAX_G_double_to_IEEE_little_double (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("VAX G float", "IEEE little endian format");
 }
 
 static void
-Cray_to_IEEE_little_double (void * /* d */, int /* len */)
+Cray_to_IEEE_little_double (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("Cray", "IEEE little endian format");
 }
 
 static void
-IEEE_big_float_to_IEEE_little_float (void *d, int len)
+IEEE_big_float_to_IEEE_little_float (void *d, octave_idx_type len)
 {
   swap_bytes<4> (d, len);
 }
 
 static void
-VAX_D_float_to_IEEE_little_float (void * /* d */, int /* len */)
+VAX_D_float_to_IEEE_little_float (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("VAX D float", "IEEE little endian format");
 }
 
 static void
-VAX_G_float_to_IEEE_little_float (void * /* d */, int /* len */)
+VAX_G_float_to_IEEE_little_float (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("VAX G float", "IEEE little endian format");
 }
 
 static void
-Cray_to_IEEE_little_float (void * /* d */, int /* len */)
+Cray_to_IEEE_little_float (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("Cray", "IEEE little endian format");
 }
 
 static void
-IEEE_little_double_to_IEEE_big_double (void *d, int len)
+IEEE_little_double_to_IEEE_big_double (void *d, octave_idx_type len)
 {
   swap_bytes<8> (d, len);
 }
 
 static void
-VAX_D_double_to_IEEE_big_double (void * /* d */, int /* len */)
+VAX_D_double_to_IEEE_big_double (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("VAX D float", "IEEE big endian format");
 }
 
 static void
-VAX_G_double_to_IEEE_big_double (void * /* d */, int /* len */)
+VAX_G_double_to_IEEE_big_double (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("VAX G float", "IEEE big endian format");
 }
 
 static void
-Cray_to_IEEE_big_double (void * /* d */, int /* len */)
+Cray_to_IEEE_big_double (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("Cray", "IEEE big endian format");
 }
 
 static void
-IEEE_little_float_to_IEEE_big_float (void *d, int len)
+IEEE_little_float_to_IEEE_big_float (void *d, octave_idx_type len)
 {
   swap_bytes<4> (d, len);
 }
 
 static void
-VAX_D_float_to_IEEE_big_float (void * /* d */, int /* len */)
+VAX_D_float_to_IEEE_big_float (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("VAX D float", "IEEE big endian format");
 }
 
 static void
-VAX_G_float_to_IEEE_big_float (void * /* d */, int /* len */)
+VAX_G_float_to_IEEE_big_float (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("VAX G float", "IEEE big endian format");
 }
 
 static void
-Cray_to_IEEE_big_float (void * /* d */, int /* len */)
+Cray_to_IEEE_big_float (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("Cray", "IEEE big endian format");
 }
 
 static void
-IEEE_little_double_to_VAX_D_double (void * /* d */, int /* len */)
+IEEE_little_double_to_VAX_D_double (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("IEEE little endian", "VAX D");
 }
 
 static void
-IEEE_big_double_to_VAX_D_double (void * /* d */, int /* len */)
+IEEE_big_double_to_VAX_D_double (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("IEEE big endian", "VAX D");
 }
 
 static void
-VAX_G_double_to_VAX_D_double (void * /* d */, int /* len */)
+VAX_G_double_to_VAX_D_double (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("VAX G float", "VAX D");
 }
 
 static void
-Cray_to_VAX_D_double (void * /* d */, int /* len */)
+Cray_to_VAX_D_double (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("Cray", "VAX D");
 }
 
 static void
-IEEE_little_float_to_VAX_D_float (void * /* d */, int /* len */)
+IEEE_little_float_to_VAX_D_float (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("IEEE little endian", "VAX D");
 }
 
 static void
-IEEE_big_float_to_VAX_D_float (void * /* d */, int /* len */)
+IEEE_big_float_to_VAX_D_float (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("IEEE big endian", "VAX D");
 }
 
 static void
-VAX_G_float_to_VAX_D_float (void * /* d */, int /* len */)
+VAX_G_float_to_VAX_D_float (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("VAX G float", "VAX D");
 }
 
 static void
-Cray_to_VAX_D_float (void * /* d */, int /* len */)
+Cray_to_VAX_D_float (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("Cray", "VAX D");
 }
 
 static void
-IEEE_little_double_to_VAX_G_double (void * /* d */, int /* len */)
+IEEE_little_double_to_VAX_G_double (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("IEEE little endian", "VAX G");
 }
 
 static void
-IEEE_big_double_to_VAX_G_double (void * /* d */, int /* len */)
+IEEE_big_double_to_VAX_G_double (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("IEEE big endian", "VAX G");
 }
 
 static void
-VAX_D_double_to_VAX_G_double (void * /* d */, int /* len */)
+VAX_D_double_to_VAX_G_double (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("VAX D float", "VAX G");
 }
 
 static void
-Cray_to_VAX_G_double (void * /* d */, int /* len */)
+Cray_to_VAX_G_double (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("VAX G float", "VAX G");
 }
 
 static void
-IEEE_little_float_to_VAX_G_float (void * /* d */, int /* len */)
+IEEE_little_float_to_VAX_G_float (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("IEEE little endian", "VAX G");
 }
 
 static void
-IEEE_big_float_to_VAX_G_float (void * /* d */, int /* len */)
+IEEE_big_float_to_VAX_G_float (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("IEEE big endian", "VAX G");
 }
 
 static void
-VAX_D_float_to_VAX_G_float (void * /* d */, int /* len */)
+VAX_D_float_to_VAX_G_float (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("VAX D float", "VAX G");
 }
 
 static void
-Cray_to_VAX_G_float (void * /* d */, int /* len */)
+Cray_to_VAX_G_float (void * /* d */, octave_idx_type /* len */)
 {
   gripe_data_conversion ("VAX G float", "VAX G");
 }
 
 void
-do_double_format_conversion (void *data, int len,
+do_double_format_conversion (void *data, octave_idx_type len,
                              oct_mach_info::float_format from_fmt,
                              oct_mach_info::float_format to_fmt)
 {
@@ -859,7 +859,7 @@
 }
 
 void
-do_float_format_conversion (void *data, int len,
+do_float_format_conversion (void *data, octave_idx_type len,
                             oct_mach_info::float_format from_fmt,
                             oct_mach_info::float_format to_fmt)
 {
@@ -986,7 +986,7 @@
 }
 
 void
-do_float_format_conversion (void *data, size_t sz, int len,
+do_float_format_conversion (void *data, size_t sz, octave_idx_type len,
                             oct_mach_info::float_format from_fmt,
                             oct_mach_info::float_format to_fmt)
 {
@@ -1010,8 +1010,9 @@
 
 
 void
-read_doubles (std::istream& is, double *data, save_type type, int len,
-              bool swap, oct_mach_info::float_format fmt)
+read_doubles (std::istream& is, double *data, save_type type,
+              octave_idx_type len, bool swap,
+              oct_mach_info::float_format fmt)
 {
   switch (type)
     {
@@ -1044,7 +1045,7 @@
         OCTAVE_LOCAL_BUFFER (float, ptr, len);
         is.read (reinterpret_cast<char *> (ptr), 4 * len);
         do_float_format_conversion (ptr, len, fmt);
-        for (int i = 0; i < len; i++)
+        for (octave_idx_type i = 0; i < len; i++)
           data[i] = ptr[i];
       }
       break;
@@ -1066,8 +1067,9 @@
 }
 
 void
-read_floats (std::istream& is, float *data, save_type type, int len,
-              bool swap, oct_mach_info::float_format fmt)
+read_floats (std::istream& is, float *data, save_type type,
+             octave_idx_type len, bool swap,
+             oct_mach_info::float_format fmt)
 {
   switch (type)
     {
@@ -1105,7 +1107,7 @@
         OCTAVE_LOCAL_BUFFER (double, ptr, len);
         is.read (reinterpret_cast<char *> (ptr), 8 * len);
         do_double_format_conversion (ptr, len, fmt);
-        for (int i = 0; i < len; i++)
+        for (octave_idx_type i = 0; i < len; i++)
           data[i] = ptr[i];
       }
       break;
@@ -1117,7 +1119,8 @@
 }
 
 void
-write_doubles (std::ostream& os, const double *data, save_type type, int len)
+write_doubles (std::ostream& os, const double *data, save_type type,
+               octave_idx_type len)
 {
   switch (type)
     {
@@ -1165,7 +1168,8 @@
 }
 
 void
-write_floats (std::ostream& os, const float *data, save_type type, int len)
+write_floats (std::ostream& os, const float *data, save_type type,
+              octave_idx_type len)
 {
   switch (type)
     {
--- a/liboctave/data-conv.h
+++ b/liboctave/data-conv.h
@@ -92,33 +92,37 @@
   };
 
 extern OCTAVE_API void
-do_double_format_conversion (void *data, int len,
+do_double_format_conversion (void *data, octave_idx_type len,
                              oct_mach_info::float_format from_fmt,
                              oct_mach_info::float_format to_fmt
                                = oct_mach_info::native_float_format ());
 
 extern OCTAVE_API void
-do_float_format_conversion (void *data, int len,
+do_float_format_conversion (void *data, octave_idx_type len,
                             oct_mach_info::float_format from_fmt,
                             oct_mach_info::float_format to_fmt
                               = oct_mach_info::native_float_format ());
 
 extern OCTAVE_API void
-do_float_format_conversion (void *data, size_t sz, int len,
+do_float_format_conversion (void *data, size_t sz, octave_idx_type len,
                             oct_mach_info::float_format from_fmt,
                             oct_mach_info::float_format to_fmt
                               = oct_mach_info::native_float_format ());
 
 extern OCTAVE_API void
-read_doubles (std::istream& is, double *data, save_type type, int len,
-              bool swap, oct_mach_info::float_format fmt);
+read_doubles (std::istream& is, double *data, save_type type,
+              octave_idx_type len, bool swap, oct_mach_info::float_format fmt);
+
 extern OCTAVE_API void
-write_doubles (std::ostream& os, const double *data, save_type type, int len);
+write_doubles (std::ostream& os, const double *data, save_type type,
+               octave_idx_type len);
 
 extern OCTAVE_API void
-read_floats (std::istream& is, float *data, save_type type, int len,
-              bool swap, oct_mach_info::float_format fmt);
+read_floats (std::istream& is, float *data, save_type type,
+             octave_idx_type len, bool swap, oct_mach_info::float_format fmt);
+
 extern OCTAVE_API void
-write_floats (std::ostream& os, const float *data, save_type type, int len);
+write_floats (std::ostream& os, const float *data, save_type type,
+              octave_idx_type len);
 
 #endif
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,34 @@
+2010-02-22  John W. Eaton  <jwe@octave.org>
+
+	* ls-mat5.cc: Use numel instead of nelem consistently and where
+	appropriate in all functions.
+	(read_mat5_binary_element): Declare ridx and cidx as pointer to
+	octave_idx_type, not int.
+	(read_mat5_integer_data): Declare count as octave_idx_type, not int.
+	(READ_INTEGER_DATA): Loop counter is octave_idx_type, not int.
+	(OCTAVE_MAT5_INTEGER_READ): Declare n and loop counter as
+	octave_idx_type, not int.
+	(read_mat5_binary_element): Rows and columns of sparse matrix
+	are octave_idx_type, not int.  Declare nzmax and nnz as
+	octave_idx_type.  Read nzmax as 32-bit int, and assign.  Move
+	decls closer to first use.
+	(read_mat5_binary_data): Declare count as octave_idx_type, not int.
+	(read_mat5_binary_element, write_mat5_array):
+	Use octave_idx_type instead of int for numel and loop counters.
+	(write_mat5_array): Declare len and nel as octave_idx_type.
+	Move declarations closer to first use.
+	(write_mat5_tag): Declare bytes arg as octave_idx_type, not int.
+	(write_mat5_integer_data): Declare nel as octave_idx_type, not int.
+	(write_mat5_cell_array): Declare nel and loop counter as
+	octave_idx_type, not int.
+	(save_mat5_array_length): Declare nel nad loop counters as
+	octave_idx_type, not int.
+	(save_mat5_binary_element): Declare dims and counters as
+	octave_idx_type, not int. Delete unused streampos variables.
+	Call write_mat5_sparse_index_vector to write ridx and cidx.
+	Don't write element if dimension is too large to save.
+	(gripe_dim_too_large, write_mat5_sparse_index_vector): New functions.
+
 2010-02-22  Carlo de Falco <kingcrimson@tiscali.it>
 
 	* dirfns.cc (Fglob): Make glob function test more robust.
@@ -18,6 +49,8 @@
 
 2010-02-19  John W. Eaton  <jwe@octave.org>
 
+2010-02-19  John W. Eaton  <jwe@octave.org>
+
 	* DLD-FUNCTIONS/qr.cc: Increase tolerance for test.
 
 2010-02-19  Jaroslav Hajek  <highegg@gmail.com>
--- a/src/ls-mat5.cc
+++ b/src/ls-mat5.cc
@@ -123,7 +123,7 @@
 
 static void
 read_mat5_binary_data (std::istream& is, double *data,
-                       int count, bool swap, mat5_data_type type,
+                       octave_idx_type  count, bool swap, mat5_data_type type,
                        oct_mach_info::float_format flt_fmt)
 {
   
@@ -188,8 +188,8 @@
 
 template <class T>
 void
-read_mat5_integer_data (std::istream& is, T *m, int count, bool swap,
-                        mat5_data_type type)
+read_mat5_integer_data (std::istream& is, T *m, octave_idx_type count,
+                        bool swap, mat5_data_type type)
 {
 
 #define READ_INTEGER_DATA(TYPE, swap, data, size, len, stream)  \
@@ -201,7 +201,7 @@
           stream.read (reinterpret_cast<char *> (ptr), size * len); \
           if (swap) \
             swap_bytes< size > (ptr, len); \
-          for (int i = 0; i < len; i++) \
+          for (octave_idx_type i = 0; i < len; i++) \
             data[i] = ptr[i]; \
         } \
     } \
@@ -257,34 +257,50 @@
 
 }
 
-template void read_mat5_integer_data (std::istream& is, octave_int8 *m,
-                                      int count, bool swap,
-                                      mat5_data_type type);
-template void read_mat5_integer_data (std::istream& is, octave_int16 *m,
-                                      int count, bool swap,
-                                      mat5_data_type type);
-template void read_mat5_integer_data (std::istream& is, octave_int32 *m,
-                                      int count, bool swap,
-                                      mat5_data_type type);
-template void read_mat5_integer_data (std::istream& is, octave_int64 *m,
-                                      int count, bool swap,
-                                      mat5_data_type type);
-template void read_mat5_integer_data (std::istream& is, octave_uint8 *m,
-                                      int count, bool swap,
-                                      mat5_data_type type);
-template void read_mat5_integer_data (std::istream& is, octave_uint16 *m,
-                                      int count, bool swap,
-                                      mat5_data_type type);
-template void read_mat5_integer_data (std::istream& is, octave_uint32 *m,
-                                      int count, bool swap,
-                                      mat5_data_type type);
-template void read_mat5_integer_data (std::istream& is, octave_uint64 *m,
-                                      int count, bool swap,
-                                      mat5_data_type type);
+template void
+read_mat5_integer_data (std::istream& is, octave_int8 *m,
+                        octave_idx_type count, bool swap,
+                        mat5_data_type type);
+
+template void
+read_mat5_integer_data (std::istream& is, octave_int16 *m,
+                        octave_idx_type count, bool swap,
+                        mat5_data_type type);
+
+template void
+read_mat5_integer_data (std::istream& is, octave_int32 *m,
+                        octave_idx_type count, bool swap,
+                        mat5_data_type type);
+
+template void
+read_mat5_integer_data (std::istream& is, octave_int64 *m,
+                        octave_idx_type count, bool swap,
+                        mat5_data_type type);
 
-template void read_mat5_integer_data (std::istream& is, int *m,
-                                      int count, bool swap,
-                                      mat5_data_type type);
+template void
+read_mat5_integer_data (std::istream& is, octave_uint8 *m,
+                        octave_idx_type count, bool swap,
+                        mat5_data_type type);
+
+template void
+read_mat5_integer_data (std::istream& is, octave_uint16 *m,
+                        octave_idx_type count, bool swap,
+                        mat5_data_type type);
+
+template void
+read_mat5_integer_data (std::istream& is, octave_uint32 *m,
+                        octave_idx_type count, bool swap,
+                        mat5_data_type type);
+
+template void
+read_mat5_integer_data (std::istream& is, octave_uint64 *m,
+                        octave_idx_type count, bool swap,
+                        mat5_data_type type);
+
+template void
+read_mat5_integer_data (std::istream& is, int *m,
+                        octave_idx_type count, bool swap,
+                        mat5_data_type type);
 
 #define OCTAVE_MAT5_INTEGER_READ(TYP) \
   { \
@@ -298,7 +314,7 @@
             goto data_read_error; \
           } \
   \
-        int n = re.length (); \
+        octave_idx_type n = re.numel (); \
         tmp_pos = is.tellg (); \
         read_mat5_integer_data (is, re.fortran_vec (), n, swap, \
                                 static_cast<enum mat5_data_type> (type)); \
@@ -323,7 +339,7 @@
                 goto data_read_error; \
               } \
   \
-            n = im.length (); \
+            n = im.numel (); \
             read_mat5_binary_data (is, im.fortran_vec (), n, swap, \
                                    static_cast<enum mat5_data_type> (type), flt_fmt); \
   \
@@ -336,7 +352,7 @@
   \
             ComplexNDArray ctmp (dims); \
   \
-            for (int i = 0; i < n; i++) \
+            for (octave_idx_type i = 0; i < n; i++) \
               ctmp(i) = Complex (re(i).double_value (), im(i)); \
   \
             tc = ctmp;  \
@@ -406,44 +422,41 @@
 {
   std::string retval;
 
-  // These are initialized here instead of closer to where they are
-  // first used to avoid errors from gcc about goto crossing
+  global = false;
+
+  // NOTE: these are initialized here instead of closer to where they
+  // are first used to avoid errors from gcc about goto crossing
   // initialization of variable.
 
-  oct_mach_info::float_format flt_fmt = oct_mach_info::flt_fmt_unknown;
-  int32_t type = 0;
-  std::string classname;
+  bool imag;
   bool isclass = false;
-  bool imag;
   bool logicalvar;
+  dim_vector dims;
   enum arrayclasstype arrayclass;
-  int32_t nzmax;
-  int32_t flags;
-  dim_vector dims;
-  int32_t len;
-  int32_t element_length;
-  std::streampos pos;
-  int16_t number;
-  number = *(reinterpret_cast<const int16_t *>("\x00\x01"));
-
-  global = false;
+  int16_t number = *(reinterpret_cast<const int16_t *>("\x00\x01"));
+  octave_idx_type nzmax;
+  std::string classname;
 
   // MAT files always use IEEE floating point
+  oct_mach_info::float_format flt_fmt = oct_mach_info::flt_fmt_unknown;
   if ((number == 1) ^ swap)
     flt_fmt = oct_mach_info::flt_fmt_ieee_big_endian;
   else
     flt_fmt = oct_mach_info::flt_fmt_ieee_little_endian;
 
   // element type and length
+  int32_t type = 0;
+  int32_t element_length;
   if (read_mat5_tag (is, swap, type, element_length))
     return retval;                      // EOF
 
 #ifdef HAVE_ZLIB
   if (type == miCOMPRESSED)
     {
-      // If C++ allowed us direct access to the file descriptor of an ifstream 
-      // in a uniform way, the code below could be vastly simplified, and 
-      // additional copies of the data in memory wouldn't be needed!!
+      // If C++ allowed us direct access to the file descriptor of an
+      // ifstream in a uniform way, the code below could be vastly
+      // simplified, and additional copies of the data in memory
+      // wouldn't be needed.
 
       OCTAVE_LOCAL_BUFFER (char, inbuf, element_length);
       is.read (inbuf, element_length);
@@ -465,8 +478,9 @@
 
           // FIXME -- find a way to avoid casting away const here!
 
-          int err = uncompress (reinterpret_cast<Bytef *> (const_cast<char *> (outbuf.c_str ())), &destLen, 
-                                reinterpret_cast<Bytef *> (inbuf), element_length);
+          int err = uncompress (reinterpret_cast<Bytef *> (const_cast<char *> (outbuf.c_str ())),
+                                &destLen, reinterpret_cast<Bytef *> (inbuf),
+                                element_length);
 
           if (err != Z_OK)
             error ("load: error uncompressing data element");
@@ -484,6 +498,8 @@
     }
 #endif
 
+  std::streampos pos;
+
   if (type != miMATRIX)
     {
       pos = is.tellg ();
@@ -500,18 +516,27 @@
   pos = is.tellg ();
 
   // array flags subelement
+  int32_t len;
   if (read_mat5_tag (is, swap, type, len) || type != miUINT32 || len != 8)
     {
       error ("load: invalid array flags subelement");
       goto early_read_error;
     }
 
+  int32_t flags;
   read_int (is, swap, flags);
+
   imag = (flags & 0x0800) != 0; // has an imaginary part?
+
   global = (flags & 0x0400) != 0; // global variable?
+
   logicalvar = (flags & 0x0200) != 0; // boolean ?
+
   arrayclass = static_cast<arrayclasstype> (flags & 0xff);
-  read_int (is, swap, nzmax);   // max number of non-zero in sparse
+  
+  int32_t tmp_nzmax;
+  read_int (is, swap, tmp_nzmax);   // max number of non-zero in sparse
+  nzmax = tmp_nzmax;
   
   // dimensions array subelement
   if (arrayclass != MAT_FILE_WORKSPACE_CLASS)
@@ -575,9 +600,9 @@
       {
         Cell cell_array (dims);
 
-        int n = cell_array.length ();
+        octave_idx_type n = cell_array.numel ();
 
-        for (int i = 0; i < n; i++)
+        for (octave_idx_type i = 0; i < n; i++)
           {
             octave_value tc2;
 
@@ -598,34 +623,26 @@
       break;
 
     case MAT_FILE_SPARSE_CLASS:
-#if SIZEOF_INT != SIZEOF_OCTAVE_IDX_TYPE
-      warning ("load: sparse objects are not implemented");
-      goto skip_ahead;
-#else
       {
-        int nr = dims(0);
-        int nc = dims(1);
+        octave_idx_type nr = dims(0);
+        octave_idx_type nc = dims(1);
         SparseMatrix sm;
         SparseComplexMatrix scm;
-        int *ridx;
-        int *cidx;
+        octave_idx_type *ridx;
+        octave_idx_type *cidx;
         double *data;
 
         // Setup return value
         if (imag)
           {
-            scm = SparseComplexMatrix (static_cast<octave_idx_type> (nr),
-                                       static_cast<octave_idx_type> (nc),
-                                       static_cast<octave_idx_type> (nzmax));
+            scm = SparseComplexMatrix (nr, nc, nzmax);
             ridx = scm.ridx ();
             cidx = scm.cidx ();
             data = 0;
           }
         else
           {
-            sm = SparseMatrix (static_cast<octave_idx_type> (nr),
-                               static_cast<octave_idx_type> (nc),
-                               static_cast<octave_idx_type> (nzmax));
+            sm = SparseMatrix (nr, nc, nzmax);
             ridx = sm.ridx ();
             cidx = sm.cidx ();
             data = sm.data ();
@@ -680,11 +697,11 @@
             goto data_read_error;
           }
 
-        int32_t nnz = cidx[nc];
+        octave_idx_type nnz = cidx[nc];
         NDArray re;
         if (imag)
           {
-            re = NDArray (dim_vector (static_cast<int> (nnz)));
+            re = NDArray (dim_vector (nnz));
             data = re.fortran_vec ();
           }
 
@@ -721,7 +738,7 @@
                 goto data_read_error;
               }
 
-            for (int i = 0; i < nnz; i++)
+            for (octave_idx_type i = 0; i < nnz; i++)
               scm.xdata (i) = Complex (re (i), im (i));
 
             tc = scm;
@@ -729,7 +746,6 @@
         else
           tc = sm;
       }
-#endif
       break;
 
     case MAT_FILE_FUNCTION_CLASS:
@@ -1144,10 +1160,10 @@
         if (logicalvar)
           {
             uint8NDArray in = tc.uint8_array_value ();
-            int nel = in.nelem ();
+            octave_idx_type nel = in.numel ();
             boolNDArray out (dims);
             
-            for (int i = 0; i < nel; i++)
+            for (octave_idx_type i = 0; i < nel; i++)
               out (i) = in(i).bool_value ();
 
             tc = out;
@@ -1198,7 +1214,7 @@
             goto data_read_error;
           }
 
-        int n = re.length ();
+        octave_idx_type n = re.numel ();
         tmp_pos = is.tellg ();
         read_mat5_binary_data (is, re.fortran_vec (), n, swap,
                                static_cast<enum mat5_data_type> (type), flt_fmt);
@@ -1219,7 +1235,7 @@
 
             boolNDArray out (dims);
             
-            for (int i = 0; i < n; i++)
+            for (octave_idx_type i = 0; i < n; i++)
               out (i) = static_cast<bool> (re (i));
 
             tc = out;
@@ -1236,7 +1252,7 @@
                 goto data_read_error;
               }
 
-            n = im.length ();
+            n = im.numel ();
             read_mat5_binary_data (is, im.fortran_vec (), n, swap,
                                    static_cast<enum mat5_data_type> (type), flt_fmt);
 
@@ -1249,7 +1265,7 @@
 
             ComplexNDArray ctmp (dims);
 
-            for (int i = 0; i < n; i++)
+            for (octave_idx_type i = 0; i < n; i++)
               ctmp(i) = Complex (re(i), im(i));
 
             tc = ctmp;
@@ -1261,7 +1277,7 @@
                 if (type == miUTF16 || type == miUTF32)
                   {
                     bool found_big_char = false;
-                    for (int i = 0; i < n; i++)
+                    for (octave_idx_type i = 0; i < n; i++)
                       {
                         if (re(i) > 127) {
                           re(i) = '?';
@@ -1281,7 +1297,7 @@
                     // replace with 0x3F for '?'... Give the user a warning
 
                     bool utf8_multi_byte = false;
-                    for (int i = 0; i < n; i++)
+                    for (octave_idx_type i = 0; i < n; i++)
                       {
                         unsigned char a = static_cast<unsigned char> (re(i));
                         if (a > 0x7f)
@@ -1292,7 +1308,7 @@
                       {
                         warning ("load: can not read multi-byte encoded UTF8 characters.");
                         warning ("      Replacing unreadable characters with '?'.");
-                        for (int i = 0; i < n; i++)
+                        for (octave_idx_type i = 0; i < n; i++)
                           {
                             unsigned char a = static_cast<unsigned char> (re(i));
                             if (a > 0x7f)
@@ -1377,7 +1393,7 @@
       if (tc.is_uint8_type ())
         {
           const uint8NDArray itmp = tc.uint8_array_value();
-          octave_idx_type ilen = itmp.nelem ();
+          octave_idx_type ilen = itmp.numel ();
 
           // Why should I have to initialize outbuf as just overwrite
           std::string outbuf (ilen - 7, ' ');
@@ -1405,7 +1421,7 @@
 }
 
 static int 
-write_mat5_tag (std::ostream& is, int type, int bytes)
+write_mat5_tag (std::ostream& is, int type, octave_idx_type bytes)
 {
   int32_t temp;
 
@@ -1433,12 +1449,7 @@
 static void 
 write_mat5_array (std::ostream& os, const NDArray& m, bool save_as_floats)
 {
-  int nel = m.nelem ();
-  double max_val, min_val;
   save_type st = LS_DOUBLE;
-  mat5_data_type mst;
-  int size;
-  unsigned len;
   const double *data = m.data ();
 
 // Have to use copy here to avoid writing over data accessed via
@@ -1448,7 +1459,7 @@
   do \
     { \
       OCTAVE_LOCAL_BUFFER (TYPE, ptr, count); \
-      for (int i = 0; i < count; i++) \
+      for (octave_idx_type i = 0; i < count; i++) \
         ptr[i] = static_cast<TYPE> (data[i]); \
       stream.write (reinterpret_cast<char *> (ptr), count * sizeof (TYPE)); \
     } \
@@ -1465,9 +1476,12 @@
         st = LS_FLOAT;
     }
 
+  double max_val, min_val;
   if (m.all_integers (max_val, min_val))
     st = get_save_type (max_val, min_val);
 
+  mat5_data_type mst;
+  int size;
   switch (st)
     {
     default:
@@ -1481,7 +1495,9 @@
     case LS_INT:     mst = miINT32;  size = 4; break;
     }
 
-  len = nel*size;
+  octave_idx_type nel = m.numel ();
+  octave_idx_type len = nel*size;
+
   write_mat5_tag (os, mst, len);
 
   {
@@ -1542,7 +1558,8 @@
 
 template <class T>
 void 
-write_mat5_integer_data (std::ostream& os, const T *m, int size, int nel)
+write_mat5_integer_data (std::ostream& os, const T *m, int size,
+                         octave_idx_type nel)
 {
   mat5_data_type mst;
   unsigned len;
@@ -1592,24 +1609,41 @@
     }
 }
 
-template void write_mat5_integer_data (std::ostream& os, const octave_int8 *m,
-                                       int size, int nel);
-template void write_mat5_integer_data (std::ostream& os, const octave_int16 *m,
-                                       int size, int nel);
-template void write_mat5_integer_data (std::ostream& os, const octave_int32 *m,
-                                       int size, int nel);
-template void write_mat5_integer_data (std::ostream& os, const octave_int64 *m,
-                                       int size, int nel);
-template void write_mat5_integer_data (std::ostream& os, const octave_uint8 *m,
-                                       int size, int nel);
-template void write_mat5_integer_data (std::ostream& os, const octave_uint16 *m,
-                                       int size, int nel);
-template void write_mat5_integer_data (std::ostream& os, const octave_uint32 *m,
-                                       int size, int nel);
-template void write_mat5_integer_data (std::ostream& os, const octave_uint64 *m,
-                                       int size, int nel);
-template void write_mat5_integer_data (std::ostream& os, const int *m, 
-                                       int size, int nel);
+template void
+write_mat5_integer_data (std::ostream& os, const octave_int8 *m,
+                         int size, octave_idx_type nel);
+
+template void
+write_mat5_integer_data (std::ostream& os, const octave_int16 *m,
+                         int size, octave_idx_type nel);
+
+template void
+write_mat5_integer_data (std::ostream& os, const octave_int32 *m,
+                         int size, octave_idx_type nel);
+
+template void
+write_mat5_integer_data (std::ostream& os, const octave_int64 *m,
+                         int size, octave_idx_type nel);
+
+template void
+write_mat5_integer_data (std::ostream& os, const octave_uint8 *m,
+                         int size, octave_idx_type nel);
+
+template void
+write_mat5_integer_data (std::ostream& os, const octave_uint16 *m,
+                         int size, octave_idx_type nel);
+
+template void
+write_mat5_integer_data (std::ostream& os, const octave_uint32 *m,
+                         int size, octave_idx_type nel);
+
+template void
+write_mat5_integer_data (std::ostream& os, const octave_uint64 *m,
+                         int size, octave_idx_type nel);
+
+template void
+write_mat5_integer_data (std::ostream& os, const int *m, 
+                         int size, octave_idx_type nel);
 
 // Write out cell element values in the cell array to OS, preceded by
 // the appropriate tag.
@@ -1618,9 +1652,9 @@
 write_mat5_cell_array (std::ostream& os, const Cell& cell,
                        bool mark_as_global, bool save_as_floats)
 {
-  int nel = cell.nelem ();
+  octave_idx_type nel = cell.numel ();
 
-  for (int i = 0; i < nel; i++)
+  for (octave_idx_type i = 0; i < nel; i++)
     {
       octave_value ov = cell(i);
 
@@ -1633,7 +1667,8 @@
 }
 
 int
-save_mat5_array_length (const double* val, int nel, bool save_as_floats)
+save_mat5_array_length (const double* val, octave_idx_type nel,
+                        bool save_as_floats)
 {
   if (nel > 0)
     {
@@ -1642,7 +1677,7 @@
       if (save_as_floats)
         {
           bool too_large_for_float = false;
-          for (int i = 0; i < nel; i++)
+          for (octave_idx_type i = 0; i < nel; i++)
             {
               double tmp = val [i];
 
@@ -1706,18 +1741,19 @@
 }
 
 int
-save_mat5_array_length (const Complex* val, int nel, bool save_as_floats)
+save_mat5_array_length (const Complex* val, octave_idx_type nel,
+                        bool save_as_floats)
 {
   int ret;
 
   OCTAVE_LOCAL_BUFFER (double, tmp, nel);
 
-  for (int i = 1; i < nel; i++)
+  for (octave_idx_type i = 1; i < nel; i++)
     tmp[i] = std::real (val[i]);
 
   ret = save_mat5_array_length (tmp, nel, save_as_floats);
 
-  for (int i = 1; i < nel; i++)
+  for (octave_idx_type i = 1; i < nel; i++)
     tmp[i] = std::imag (val[i]);
 
   ret += save_mat5_array_length (tmp, nel, save_as_floats);
@@ -1729,8 +1765,8 @@
 save_mat5_element_length (const octave_value& tc, const std::string& name, 
                           bool save_as_floats, bool mat7_format)
 {
-  int max_namelen = (mat7_format ? 63 : 31);
-  int len = name.length ();
+  size_t max_namelen = (mat7_format ? 63 : 31);
+  size_t len = name.length ();
   std::string cname = tc.class_name ();
   int ret = 32;
 
@@ -1743,67 +1779,67 @@
     {
       charNDArray chm = tc.char_array_value ();
       ret += 8;
-      if (chm.nelem () > 2)
-        ret += PAD (2 * chm.nelem ());
+      if (chm.numel () > 2)
+        ret += PAD (2 * chm.numel ());
     }
   else if (tc.is_sparse_type ())
     {
       if (tc.is_complex_type ())
         {
           SparseComplexMatrix m = tc.sparse_complex_matrix_value ();
-          int nc = m.cols ();
-          int nnz = m.nzmax ();
+          octave_idx_type nc = m.cols ();
+          octave_idx_type nnz = m.nzmax ();
 
           ret += 16 + PAD (nnz * sizeof (int)) + PAD ((nc + 1) * sizeof (int)) +
-            save_mat5_array_length (m.data (), m.nelem (), save_as_floats);
+            save_mat5_array_length (m.data (), nnz, save_as_floats);
         }
       else
         {
           SparseMatrix m = tc.sparse_matrix_value ();
-          int nc = m.cols ();
-          int nnz = m.nzmax ();
+          octave_idx_type nc = m.cols ();
+          octave_idx_type nnz = m.nzmax ();
 
           ret += 16 + PAD (nnz * sizeof (int)) + PAD ((nc + 1) * sizeof (int)) +
-            save_mat5_array_length (m.data (), m.nelem (), save_as_floats);
+            save_mat5_array_length (m.data (), nnz, save_as_floats);
         }
     }
 
 #define INT_LEN(nel, size) \
   { \
     ret += 8; \
-    int sz = nel * size; \
+    octave_idx_type sz = nel * size; \
     if (sz > 4) \
       ret += PAD (sz);  \
   }
 
   else if (cname == "int8")
-    INT_LEN (tc.int8_array_value ().nelem (), 1)
+    INT_LEN (tc.int8_array_value ().numel (), 1)
   else if (cname == "int16")
-    INT_LEN (tc.int16_array_value ().nelem (), 2)
+    INT_LEN (tc.int16_array_value ().numel (), 2)
   else if (cname == "int32")
-    INT_LEN (tc.int32_array_value ().nelem (), 4)
+    INT_LEN (tc.int32_array_value ().numel (), 4)
   else if (cname == "int64")
-    INT_LEN (tc.int64_array_value ().nelem (), 8)
+    INT_LEN (tc.int64_array_value ().numel (), 8)
   else if (cname == "uint8")
-    INT_LEN (tc.uint8_array_value ().nelem (), 1)
+    INT_LEN (tc.uint8_array_value ().numel (), 1)
   else if (cname == "uint16")
-    INT_LEN (tc.uint16_array_value ().nelem (), 2)
+    INT_LEN (tc.uint16_array_value ().numel (), 2)
   else if (cname == "uint32")
-    INT_LEN (tc.uint32_array_value ().nelem (), 4)
+    INT_LEN (tc.uint32_array_value ().numel (), 4)
   else if (cname == "uint64")
-    INT_LEN (tc.uint64_array_value ().nelem (), 8)
+    INT_LEN (tc.uint64_array_value ().numel (), 8)
   else if (tc.is_bool_type ())
-    INT_LEN (tc.bool_array_value ().nelem (), 1)
+    INT_LEN (tc.bool_array_value ().numel (), 1)
   else if (tc.is_real_scalar () || tc.is_real_matrix () || tc.is_range ())
     {
       NDArray m = tc.array_value ();
-      ret += save_mat5_array_length (m.fortran_vec (), m.nelem (),
+      ret += save_mat5_array_length (m.fortran_vec (), m.numel (),
                                      save_as_floats);
     }
   else if (tc.is_cell ())
     {
       Cell cell = tc.cell_value ();
-      int nel = cell.nelem ();
+      octave_idx_type nel = cell.numel ();
 
       for (int i = 0; i < nel; i++)
         ret += 8 + 
@@ -1812,21 +1848,21 @@
   else if (tc.is_complex_scalar () || tc.is_complex_matrix ()) 
     {
       ComplexNDArray m = tc.complex_array_value ();
-      ret += save_mat5_array_length (m.fortran_vec (), m.nelem (),
+      ret += save_mat5_array_length (m.fortran_vec (), m.numel (),
                                      save_as_floats);
     }
   else if (tc.is_map () || tc.is_inline_function () || tc.is_object ()) 
     {
       int fieldcnt = 0;
       const Octave_map m = tc.map_value ();
-      int nel = m.numel ();
+      octave_idx_type nel = m.numel ();
 
       if (tc.is_inline_function ())
         // length of "inline" is 6
         ret += 8 + PAD (6 > max_namelen ? max_namelen : 6);
       else if (tc.is_object ())
         {
-          int classlen = tc.class_name (). length ();
+          size_t classlen = tc.class_name (). length ();
 
           ret += 8 + PAD (classlen > max_namelen ? max_namelen : classlen);
         }
@@ -1837,7 +1873,7 @@
       ret += 16 + fieldcnt * (max_namelen + 1);
 
 
-      for (int j = 0; j < nel; j++)
+      for (octave_idx_type j = 0; j < nel; j++)
         {
 
           for (Octave_map::const_iterator i = m.begin (); i != m.end (); i++)
@@ -1855,6 +1891,28 @@
   return ret;
 }
 
+static void
+write_mat5_sparse_index_vector (std::ostream& os,
+                                const octave_idx_type *idx,
+                                octave_idx_type nel)
+{
+  int tmp = sizeof (int);
+
+  OCTAVE_LOCAL_BUFFER (int32_t, tmp_idx, nel);
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    tmp_idx[i] = idx[i];
+
+  write_mat5_integer_data (os, tmp_idx, -tmp, nel);
+}
+
+static void
+gripe_dim_too_large (const std::string& name)
+{
+  warning ("save: skipping %s: dimension too large for MAT format",
+           name.c_str ());
+}
+
 // save the data from TC along with the corresponding NAME on stream
 // OS in the MatLab version 5 binary format.  Return true on success.
 
@@ -1864,11 +1922,57 @@
                           bool mark_as_global, bool mat7_format,
                           bool save_as_floats, bool compressing) 
 {
-  int32_t flags=0;
-  int32_t nnz=0;
-  std::streampos fixup, contin;
+  int32_t flags = 0;
+  int32_t nnz_32 = 0;
   std::string cname = tc.class_name ();
-  int max_namelen = (mat7_format ? 63 : 31);
+  size_t max_namelen = (mat7_format ? 63 : 31);
+
+  dim_vector dv = tc.dims ();
+  int nd = tc.ndims ();
+  int dim_len = 4*nd;
+
+  static octave_idx_type max_dim_val = std::numeric_limits<int32_t>::max ();
+
+  for (int i = 0; i < nd; i++)
+    {
+      if (dv(i) > max_dim_val)
+        {
+          gripe_dim_too_large (name);
+          goto skip_to_next;
+        }
+    }
+
+  if (tc.is_sparse_type ())
+    {
+      octave_idx_type nnz;
+      octave_idx_type nc;
+
+      if (tc.is_complex_type ())
+        {
+          SparseComplexMatrix scm = tc.sparse_complex_matrix_value ();
+          nnz = scm.nzmax ();
+          nc = scm.cols ();
+        }
+      else
+        {
+          SparseMatrix sm = tc.sparse_matrix_value ();
+          nnz = sm.nzmax ();
+          nc = sm.cols ();
+        }
+
+      if (nnz > max_dim_val || nc + 1 > max_dim_val)
+        {
+          gripe_dim_too_large (name);
+          goto skip_to_next;
+        }
+
+      nnz_32 = nnz;
+    }
+  else if (dv.numel () > max_dim_val)
+    {
+      gripe_dim_too_large (name);
+      goto skip_to_next;
+    }
 
 #ifdef HAVE_ZLIB
   if (mat7_format && !compressing)
@@ -1894,7 +1998,9 @@
           if (compress (reinterpret_cast<Bytef *> (out_buf), &destLen, 
                         reinterpret_cast<const Bytef *> (buf_str.c_str ()), srcLen) == Z_OK)
             {
-              write_mat5_tag (os, miCOMPRESSED, static_cast<int> (destLen)); 
+              write_mat5_tag (os, miCOMPRESSED,
+                              static_cast<octave_idx_type> (destLen)); 
+
               os.write (out_buf, destLen);
             }
           else
@@ -1908,8 +2014,6 @@
     }
 #endif
 
-  // element type and length
-  fixup = os.tellp ();
   write_mat5_tag (os, miMATRIX, save_mat5_element_length 
                   (tc, name, save_as_floats, mat7_format));
   
@@ -1944,19 +2048,7 @@
   else if (cname == "uint64")
     flags |= MAT_FILE_UINT64_CLASS;
   else if (tc.is_sparse_type ())
-    {
-      flags |= MAT_FILE_SPARSE_CLASS;
-      if (tc.is_complex_type ())
-        {
-          SparseComplexMatrix scm = tc.sparse_complex_matrix_value ();
-          nnz = scm.nzmax ();
-        }
-      else
-        {
-          SparseMatrix sm = tc.sparse_matrix_value ();
-          nnz = sm.nzmax ();
-        }
-    }
+    flags |= MAT_FILE_SPARSE_CLASS;
   else if (tc.is_real_scalar ())
     flags |= MAT_FILE_DOUBLE_CLASS;
   else if (tc.is_real_matrix () || tc.is_range ())
@@ -1978,31 +2070,25 @@
     }
 
   os.write (reinterpret_cast<char *> (&flags), 4);
-  os.write (reinterpret_cast<char *> (&nnz), 4);
+  os.write (reinterpret_cast<char *> (&nnz_32), 4);
 
-  {
-    dim_vector dv = tc.dims ();
-    int nd = tc.ndims ();
-    int dim_len = 4*nd;
-
-    write_mat5_tag (os, miINT32, dim_len);
+  write_mat5_tag (os, miINT32, dim_len);
 
-    for (int i = 0; i < nd; i++)
-      {
-        int32_t n = dv(i);
-        os.write (reinterpret_cast<char *> (&n), 4);
-      }
+  for (int i = 0; i < nd; i++)
+    {
+      int32_t n = dv(i);
+      os.write (reinterpret_cast<char *> (&n), 4);
+    }
 
-    if (PAD (dim_len) > dim_len)
-      {
-        static char buf[9]="\x00\x00\x00\x00\x00\x00\x00\x00";
-        os.write (buf, PAD (dim_len) - dim_len);
-      }
-  }
+  if (PAD (dim_len) > dim_len)
+    {
+      static char buf[9]="\x00\x00\x00\x00\x00\x00\x00\x00";
+      os.write (buf, PAD (dim_len) - dim_len);
+    }
 
   // array name subelement
   {
-    int namelen = name.length ();
+    size_t namelen = name.length ();
 
     if (namelen > max_namelen)
       namelen = max_namelen; // only 31 or 63 char names permitted in mat file
@@ -2020,16 +2106,16 @@
   if (tc.is_string ())
     {
       charNDArray chm = tc.char_array_value ();
-      int nel = chm.nelem ();
-      int len = nel*2;
-      int paddedlength = PAD (len);
+      octave_idx_type nel = chm.numel ();
+      octave_idx_type len = nel*2;
+      octave_idx_type paddedlength = PAD (len);
 
       OCTAVE_LOCAL_BUFFER (int16_t, buf, nel+3);
       write_mat5_tag (os, miUINT16, len);
 
       const char *s = chm.data ();
 
-      for (int i = 0; i < nel; i++)
+      for (octave_idx_type i = 0; i < nel; i++)
         buf[i] = *s++ & 0x00FF;
 
       os.write (reinterpret_cast<char *> (buf), len);
@@ -2045,21 +2131,20 @@
       if (tc.is_complex_type ())
         {
           SparseComplexMatrix m = tc.sparse_complex_matrix_value ();
-          int nc = m.cols ();
+          octave_idx_type nnz = m.nnz ();
+          octave_idx_type nc = m.cols ();
 
-          int tmp = sizeof (int);
-
-          write_mat5_integer_data (os, m.ridx (), -tmp, nnz);
-          write_mat5_integer_data (os, m.cidx (), -tmp, nc + 1);
+          write_mat5_sparse_index_vector (os, m.ridx (), nnz);
+          write_mat5_sparse_index_vector (os, m.cidx (), nc + 1);
 
           NDArray buf (dim_vector (nnz, 1));
 
-          for (int i = 0; i < nnz; i++)
+          for (octave_idx_type i = 0; i < nnz; i++)
             buf (i) = std::real (m.data (i));
 
           write_mat5_array (os, buf, save_as_floats);
 
-          for (int i = 0; i < nnz; i++)
+          for (octave_idx_type i = 0; i < nnz; i++)
             buf (i) = std::imag (m.data (i));
 
           write_mat5_array (os, buf, save_as_floats);
@@ -2067,12 +2152,11 @@
       else
         {
           SparseMatrix m = tc.sparse_matrix_value ();
-          int nc = m.cols ();
+          octave_idx_type nnz = m.nnz ();
+          octave_idx_type nc = m.cols ();
 
-          int tmp = sizeof (int);
-
-          write_mat5_integer_data (os, m.ridx (), -tmp, nnz);
-          write_mat5_integer_data (os, m.cidx (), -tmp, nc + 1);
+          write_mat5_sparse_index_vector (os, m.ridx (), nnz);
+          write_mat5_sparse_index_vector (os, m.cidx (), nc + 1);
 
           // FIXME
           // Is there a way to easily do without this buffer
@@ -2088,55 +2172,55 @@
     {
       int8NDArray m = tc.int8_array_value ();
 
-      write_mat5_integer_data (os, m.fortran_vec (), -1, m.nelem ());
+      write_mat5_integer_data (os, m.fortran_vec (), -1, m.numel ());
     }
   else if (cname == "int16")
     {
       int16NDArray m = tc.int16_array_value ();
 
-      write_mat5_integer_data (os, m.fortran_vec (), -2, m.nelem ());
+      write_mat5_integer_data (os, m.fortran_vec (), -2, m.numel ());
     }
   else if (cname == "int32")
     {
       int32NDArray m = tc.int32_array_value ();
 
-      write_mat5_integer_data (os, m.fortran_vec (), -4, m.nelem ());
+      write_mat5_integer_data (os, m.fortran_vec (), -4, m.numel ());
     }
   else if (cname == "int64")
     {
       int64NDArray m = tc.int64_array_value ();
 
-      write_mat5_integer_data (os, m.fortran_vec (), -8, m.nelem ());
+      write_mat5_integer_data (os, m.fortran_vec (), -8, m.numel ());
     }
   else if (cname == "uint8")
     {
       uint8NDArray m = tc.uint8_array_value ();
 
-      write_mat5_integer_data (os, m.fortran_vec (), 1, m.nelem ());
+      write_mat5_integer_data (os, m.fortran_vec (), 1, m.numel ());
     }
   else if (cname == "uint16")
     {
       uint16NDArray m = tc.uint16_array_value ();
 
-      write_mat5_integer_data (os, m.fortran_vec (), 2, m.nelem ());
+      write_mat5_integer_data (os, m.fortran_vec (), 2, m.numel ());
     }
   else if (cname == "uint32")
     {
       uint32NDArray m = tc.uint32_array_value ();
 
-      write_mat5_integer_data (os, m.fortran_vec (), 4, m.nelem ());
+      write_mat5_integer_data (os, m.fortran_vec (), 4, m.numel ());
     }
   else if (cname == "uint64")
     {
       uint64NDArray m = tc.uint64_array_value ();
 
-      write_mat5_integer_data (os, m.fortran_vec (), 8, m.nelem ());
+      write_mat5_integer_data (os, m.fortran_vec (), 8, m.numel ());
     }
   else if (tc.is_bool_type ())
     {
       uint8NDArray m (tc.bool_array_value ());
 
-      write_mat5_integer_data (os, m.fortran_vec (), 1, m.nelem ());
+      write_mat5_integer_data (os, m.fortran_vec (), 1, m.numel ());
     }
   else if (tc.is_real_scalar () || tc.is_real_matrix () || tc.is_range ())
     {
@@ -2163,7 +2247,7 @@
       if (tc.is_inline_function () || tc.is_object ())
         {
           std::string classname = tc.is_object() ? tc.class_name () : "inline";
-          int namelen = classname.length ();
+          size_t namelen = classname.length ();
 
           if (namelen > max_namelen)
             namelen = max_namelen; // only 31 or 63 char names permitted
@@ -2199,11 +2283,9 @@
 
         octave_idx_type nf = m.nfields ();
 
-        int fieldcnt = nf;
-
         write_mat5_tag (os, miINT32, 4);
         os.write (reinterpret_cast<char *> (&maxfieldnamelength), 4);
-        write_mat5_tag (os, miINT8, fieldcnt*maxfieldnamelength);
+        write_mat5_tag (os, miINT8, nf*maxfieldnamelength);
 
         // Iterating over the list of keys will preserve the order of
         // the fields.
@@ -2220,7 +2302,7 @@
             os.write (buf, max_namelen + 1);
           }
 
-        int len = m.numel ();
+        octave_idx_type len = m.numel ();
 
         // Create temporary copy of structure contents to avoid
         // multiple calls of the contents method.
@@ -2228,7 +2310,7 @@
         for (octave_idx_type i = 0; i < nf; i++)
           elts[i] = m.contents (keys(i)).data ();
 
-        for (int j = 0; j < len; j++)
+        for (octave_idx_type j = 0; j < len; j++)
           {
             // write the data of each element
 
@@ -2249,8 +2331,7 @@
   else
     gripe_wrong_type_arg ("save", tc, false);
 
-  contin = os.tellp ();
-
+ skip_to_next:
   return true;
 
  error_cleanup: