changeset 23982:3706091dc91c

Make fread, fwrite precisions compatible with Matlab (bug #41672). * file-io.cc (Ffread): Rewrite docstring with the new sizes of various precisions. Change the default precision to "uint8" for Matlab compatibility. * data-conv.cc: Add FIXME to top of file stating that code needs review as much of it is probably obsolete now. * data-conv.cc (string_to_data_type): Change string to data type conversion so that platform-dependent types such as "short" now have fixed values which match Matlab. Re-order if/elseif tree so that most common precisions appear first.
author Rik <rik@octave.org>
date Thu, 31 Aug 2017 15:38:31 -0700
parents 6420142ff32c
children 3a07616e660b
files libinterp/corefcn/file-io.cc liboctave/util/data-conv.cc
diffstat 2 files changed, 59 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/file-io.cc	Thu Aug 31 14:00:39 2017 -0700
+++ b/libinterp/corefcn/file-io.cc	Thu Aug 31 15:38:31 2017 -0700
@@ -2330,43 +2330,43 @@
 data to read and may be one of
 
 @table @asis
-@item  @qcode{"schar"}
-@itemx @qcode{"signed char"}
-Signed character.
-
-@item  @qcode{"uchar"}
-@itemx @qcode{"unsigned char"}
-Unsigned character.
+@item @qcode{"uint8"} (default)
+8-bit unsigned integer.
 
 @item  @qcode{"int8"}
 @itemx @qcode{"integer*1"}
-
 8-bit signed integer.
 
+@item  @qcode{"uint16"}
+@itemx @qcode{"ushort"}
+@itemx @qcode{"unsigned short"}
+16-bit unsigned integer.
+
 @item  @qcode{"int16"}
 @itemx @qcode{"integer*2"}
+@itemx @qcode{"short"}
 16-bit signed integer.
 
-@item  @qcode{"int32"}
+@item  @qcode{"uint"}
+@itemx @qcode{"uint32"}
+@itemx @qcode{"unsigned int"}
+@itemx @qcode{"ulong"}
+@itemx @qcode{"unsigned long"}
+32-bit unsigned integer.
+
+@item  @qcode{"int"}
+@itemx @qcode{"int32"}
 @itemx @qcode{"integer*4"}
+@itemx @qcode{"long"}
 32-bit signed integer.
 
+@item @qcode{"uint64"}
+64-bit unsigned integer.
+
 @item  @qcode{"int64"}
 @itemx @qcode{"integer*8"}
 64-bit signed integer.
 
-@item @qcode{"uint8"}
-8-bit unsigned integer.
-
-@item @qcode{"uint16"}
-16-bit unsigned integer.
-
-@item @qcode{"uint32"}
-32-bit unsigned integer.
-
-@item @qcode{"uint64"}
-64-bit unsigned integer.
-
 @item  @qcode{"single"}
 @itemx @qcode{"float"}
 @itemx @qcode{"float32"}
@@ -2380,33 +2380,20 @@
 
 @item  @qcode{"char"}
 @itemx @qcode{"char*1"}
-Single character.
-
-@item @qcode{"short"}
-Short integer (size is platform dependent).
-
-@item @qcode{"int"}
-Integer (size is platform dependent).
-
-@item @qcode{"long"}
-Long integer (size is platform dependent).
-
-@item  @qcode{"ushort"}
-@itemx @qcode{"unsigned short"}
-Unsigned short integer (size is platform dependent).
-
-@item  @qcode{"uint"}
-@itemx @qcode{"unsigned int"}
-Unsigned integer (size is platform dependent).
-
-@item  @qcode{"ulong"}
-@itemx @qcode{"unsigned long"}
-Unsigned long integer (size is platform dependent).
+8-bit single character.
+
+@item  @qcode{"uchar"}
+@itemx @qcode{"unsigned char"}
+8-bit unsigned character.
+
+@item  @qcode{"schar"}
+@itemx @qcode{"signed char"}
+8-bit signed character.
 
 @end table
 
 @noindent
-The default precision is @qcode{"uchar"}.
+The default precision is @qcode{"uint8"}.
 
 The @var{precision} argument may also specify an optional repeat
 count.  For example, @samp{32*single} causes @code{fread} to read
@@ -2472,7 +2459,7 @@
   octave::stream os = streams.lookup (args(0), "fread");
 
   octave_value size = lo_ieee_inf_value ();
-  octave_value prec = "uchar";
+  octave_value prec = "uint8";
   octave_value skip = 0;
   octave_value arch = "unknown";
 
--- a/liboctave/util/data-conv.cc	Thu Aug 31 14:00:39 2017 -0700
+++ b/liboctave/util/data-conv.cc	Thu Aug 31 15:38:31 2017 -0700
@@ -37,6 +37,11 @@
 #include "lo-ieee.h"
 #include "oct-locbuf.h"
 
+// FIXME: Almost all platform-dependent sizes such as "short" are now defined
+// to take fixed values (such as 2B).  This was instigated for Matlab
+// compatibility (bug #41672).  It means a lot of this code is probably
+// obsolete and could be pared down or removed entirely.
+
 #if defined (OCTAVE_HAVE_LONG_LONG_INT)
 #  define FIND_SIZED_INT_TYPE(VAL, BITS, TQ, Q)                         \
   do                                                                    \
@@ -298,10 +303,23 @@
 
   std::string s = strip_spaces (str);
 
-  if (s == "int8" || s == "integer*1")
+  // Organized so most frequent precision appears first
+  if (s == "uint8")
+    retval = dt_uint8;
+  else if (s == "double" || s == "float64" || s == "real*8")
+    retval = dt_double;
+  else if (s == "single" || s == "float" || s == "float32" || s == "real*4")
+    retval = dt_single;
+  else if (s == "char" || s == "char*1")
+    retval = dt_char;
+  else if (s == "int")
+    retval = dt_int32;
+  else if (s == "uchar" || s == "unsignedchar")
+    retval = dt_uint8;
+  else if (s == "schar" || s == "signedchar")
     retval = dt_int8;
-  else if (s == "uint8")
-    retval = dt_uint8;
+  else if (s == "int8" || s == "integer*1")
+    retval = dt_int8;
   else if (s == "int16" || s == "integer*2")
     retval = dt_int16;
   else if (s == "uint16")
@@ -314,39 +332,21 @@
     retval = dt_int64;
   else if (s == "uint64")
     retval = dt_uint64;
-  else if (s == "single" || s == "float32" || s == "real*4")
-    retval = dt_single;
-  else if (s == "double" || s == "float64" || s == "real*8")
-    retval = dt_double;
-  else if (s == "char" || s == "char*1")
-    retval = dt_char;
-  else if (s == "schar" || s == "signedchar")
-    retval = dt_schar;
-  else if (s == "uchar" || s == "unsignedchar")
-    retval = dt_uchar;
   else if (s == "short")
-    GET_SIZED_INT_TYPE (short, );
+    retval = dt_int16;
   else if (s == "ushort" || s == "unsignedshort")
-    GET_SIZED_INT_TYPE (unsigned short, u);
-  else if (s == "int")
-    GET_SIZED_INT_TYPE (int, );
+    retval = dt_uint16;
   else if (s == "uint" || s == "unsignedint")
-    GET_SIZED_INT_TYPE (unsigned int, u);
+    retval = dt_uint32;
   else if (s == "long")
-    GET_SIZED_INT_TYPE (long, );
+    retval = dt_int32;
   else if (s == "ulong" || s == "unsignedlong")
-    GET_SIZED_INT_TYPE (unsigned long, u);
+    retval = dt_uint32;
+  // FIXME: The following are undocumented precisions
   else if (s == "longlong")
     GET_SIZED_INT_TYPE (long long, );
   else if (s == "ulonglong" || s == "unsignedlonglong")
     GET_SIZED_INT_TYPE (unsigned long long, u);
-  else if (s == "float")
-    {
-      if (sizeof (float) == sizeof (double))
-        retval = dt_double;
-      else
-        retval = dt_single;
-    }
   else if (s == "logical")
     retval = dt_logical;
   else