changeset 28467:159b6a1eb408

Use wide character overload to open file streams on Windows. * liboctave/system/lo-sysdep.cc, liboctave/system/lo-sysdep.h (fstream, ifstream, ofstream): Add "wrapper" functions to open file streams. * libinterp/corefcn/__fcn__.cc (F__ftp_mput__, F__ftp_mget__), libinterp/corefcn/debug.cc (do_dbtype), libinterp/corefcn/help.cc (help_system::raw_help_from_docstrings_file), libinterp/corefcn/load-save.cc (check_gzip_magic, load_save_system::get_file_format, load_save_system::dump_octave_core, load_save_system::load, load_save_system::save), libinterp/corefcn/oct-hist.cc (mk_tmp_hist_file, history_system::do_edit_history), libinterp/corefcn/urlwrite.cc (Furlwrite), libinterp/octave-value/ov-java.cc (read_java_opts, read_classpath_txt), libinterp/parse-tree/oct-parse.yy (get_file_line), liboctave/util/cmd-hist.cc (gnu_history::do_append), liboctave/util/file-info.cc (file_info::snarf_file), liboctave/util/url-transfer.cc (base_url_transfer::mget_directory, base_url_transfer::mput_directory): Use new functions. * libinterp/corefcn/dlmread.cc (dlmread): Use wide character overload for std::ifstream::open on Windows. * src/mkoctfile.in.cc (octave_u8_conv_to_encoding): Dummy function for cross-compiler. (main): Use wide character overload of std::ofstream::open on Windows.
author Markus Mützel <markus.muetzel@gmx.de>
date Fri, 12 Jun 2020 22:13:04 +0200
parents 597e7cf93cac
children e5ab4194f45d
files libinterp/corefcn/__ftp__.cc libinterp/corefcn/debug.cc libinterp/corefcn/dlmread.cc libinterp/corefcn/help.cc libinterp/corefcn/load-save.cc libinterp/corefcn/oct-hist.cc libinterp/corefcn/urlwrite.cc libinterp/octave-value/ov-java.cc libinterp/parse-tree/oct-parse.yy liboctave/system/lo-sysdep.cc liboctave/system/lo-sysdep.h liboctave/util/cmd-hist.cc liboctave/util/file-info.cc liboctave/util/url-transfer.cc src/mkoctfile.in.cc
diffstat 15 files changed, 154 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/__ftp__.cc	Fri Jun 12 11:39:35 2020 -0400
+++ b/libinterp/corefcn/__ftp__.cc	Fri Jun 12 22:13:04 2020 +0200
@@ -424,11 +424,10 @@
         }
       else
         {
-          std::string ascii_fname = octave::sys::get_ASCII_filename (file);
-
           // FIXME: Does ascii mode need to be flagged here?
-          std::ifstream ifile (ascii_fname.c_str (),
-                               std::ios::in | std::ios::binary);
+          std::ifstream ifile = 
+            octave::sys::ifstream (file.c_str (),
+                                   std::ios::in | std::ios::binary);
 
           if (! ifile.is_open ())
             error ("__ftp_mput__: unable to open file");
@@ -497,9 +496,9 @@
             url_xfer.mget_directory (sv(i), target);
           else
             {
-              std::ofstream ofile ((target + sv(i)).c_str (),
-                                   std::ios::out |
-                                   std::ios::binary);
+              std::ofstream ofile =
+                octave::sys::ofstream ((target + sv(i)).c_str (),
+                                       std::ios::out | std::ios::binary);
 
               if (! ofile.is_open ())
                 error ("__ftp_mget__: unable to open file");
--- a/libinterp/corefcn/debug.cc	Fri Jun 12 11:39:35 2020 -0400
+++ b/libinterp/corefcn/debug.cc	Fri Jun 12 22:13:04 2020 +0200
@@ -582,9 +582,7 @@
     os << "dbtype: unknown function " << name << "\n";
   else
     {
-      std::string ascii_fname = octave::sys::get_ASCII_filename (ff);
-
-      std::ifstream fs (ascii_fname.c_str (), std::ios::in);
+      std::ifstream fs = octave::sys::ifstream (ff.c_str (), std::ios::in);
 
       if (! fs)
         os << "dbtype: unable to open '" << ff << "' for reading!\n";
--- a/libinterp/corefcn/dlmread.cc	Fri Jun 12 11:39:35 2020 -0400
+++ b/libinterp/corefcn/dlmread.cc	Fri Jun 12 22:13:04 2020 +0200
@@ -228,9 +228,12 @@
 
       tname = octave::find_data_file_in_load_path ("dlmread", tname);
 
-      std::string ascii_fname = octave::sys::get_ASCII_filename (tname);
-
-      input_file.open (ascii_fname.c_str (), std::ios::in);
+#if defined (OCTAVE_USE_WINDOWS_API)
+      std::wstring wname = octave::sys::u8_to_wstring (tname);
+      input_file.open (wname.c_str (), std::ios::in);
+#else
+      input_file.open (tname.c_str (), std::ios::in);
+#endif
 
       if (! input_file)
         error ("dlmread: unable to open file '%s'", fname.c_str ());
--- a/libinterp/corefcn/help.cc	Fri Jun 12 11:39:35 2020 -0400
+++ b/libinterp/corefcn/help.cc	Fri Jun 12 22:13:04 2020 +0200
@@ -600,11 +600,8 @@
 
     if (! initialized)
       {
-        std::string ascii_fname
-          = sys::get_ASCII_filename (m_built_in_docstrings_file);
-
-        std::ifstream file (ascii_fname.c_str (),
-                            std::ios::in | std::ios::binary);
+        std::ifstream file = sys::ifstream (m_built_in_docstrings_file.c_str (),
+                                            std::ios::in | std::ios::binary);
 
         if (! file)
           error ("failed to open docstrings file: %s",
@@ -686,11 +683,8 @@
         std::streampos beg = txt_limits.first;
         std::streamoff len = txt_limits.second;
 
-        std::string ascii_fname
-          = sys::get_ASCII_filename (m_built_in_docstrings_file);
-
-        std::ifstream file (ascii_fname.c_str (),
-                            std::ios::in | std::ios::binary);
+        std::ifstream file = sys::ifstream (m_built_in_docstrings_file.c_str (),
+                                            std::ios::in | std::ios::binary);
 
         if (! file)
           error ("failed to open docstrings file: %s",
--- a/libinterp/corefcn/load-save.cc	Fri Jun 12 11:39:35 2020 -0400
+++ b/libinterp/corefcn/load-save.cc	Fri Jun 12 22:13:04 2020 +0200
@@ -167,8 +167,8 @@
 
     std::string ascii_fname = sys::get_ASCII_filename (fname);
 
-    std::ifstream file (ascii_fname.c_str (),
-                        std::ios::in | std::ios::binary);
+    std::ifstream file = sys::ifstream (fname.c_str (),
+                                        std::ios::in | std::ios::binary);
 
     unsigned char magic[2];
     if (file.read (reinterpret_cast<char *> (&magic[0]), 2)
@@ -348,8 +348,8 @@
 
     if (! use_zlib)
       {
-        std::ifstream file (ascii_fname.c_str (),
-                            std::ios::in | std::ios::binary);
+        std::ifstream file = sys::ifstream (fname.c_str (),
+                                            std::ios::in | std::ios::binary);
         if (file)
           {
             retval = get_file_format (file, orig_fname);
@@ -803,7 +803,7 @@
             else
 #endif
               {
-                std::ofstream file (fname, mode);
+                std::ofstream file = sys::ofstream (fname, mode);
 
                 if (file)
                   {
@@ -1352,9 +1352,7 @@
               else
 #endif
                 {
-                  std::string ascii_fname = sys::get_ASCII_filename (fname);
-
-                  std::ifstream file (ascii_fname.c_str (), mode);
+                  std::ifstream file = sys::ifstream (fname.c_str (), mode);
 
                   if (! file)
                     error ("load: unable to open input file '%s'",
@@ -1525,7 +1523,7 @@
             else
 #endif
               {
-                std::ofstream file (fname.c_str (), mode);
+                std::ofstream file = sys::ofstream (fname.c_str (), mode);
 
                 if (! file)
                   err_file_open ("save", fname);
--- a/libinterp/corefcn/oct-hist.cc	Fri Jun 12 11:39:35 2020 -0400
+++ b/libinterp/corefcn/oct-hist.cc	Fri Jun 12 22:13:04 2020 +0200
@@ -47,6 +47,7 @@
 #include "cmd-hist.h"
 #include "file-ops.h"
 #include "lo-mappers.h"
+#include "lo-sysdep.h"
 #include "oct-env.h"
 #include "oct-time.h"
 #include "str-vec.h"
@@ -238,7 +239,7 @@
 
     std::string name = sys::tempnam ("", "oct-");
 
-    std::fstream file (name.c_str (), std::ios::out);
+    std::ofstream file = sys::ofstream (name.c_str (), std::ios::out);
 
     if (! file)
       error ("%s: couldn't open temporary file '%s'", warn_for,
@@ -478,7 +479,7 @@
     // Write the commands to the history file since source_file
     // disables command line history while it executes.
 
-    std::fstream file (name.c_str (), std::ios::in);
+    std::fstream file = sys::fstream (name.c_str (), std::ios::in);
 
     char *line;
     //int first = 1;
--- a/libinterp/corefcn/urlwrite.cc	Fri Jun 12 11:39:35 2020 -0400
+++ b/libinterp/corefcn/urlwrite.cc	Fri Jun 12 22:13:04 2020 +0200
@@ -142,7 +142,8 @@
 
   octave::sys::file_stat fs (filename);
 
-  std::ofstream ofile (filename.c_str (), std::ios::out | std::ios::binary);
+  std::ofstream ofile =
+    octave::sys::ofstream (filename.c_str (), std::ios::out | std::ios::binary);
 
   if (! ofile.is_open ())
     error ("urlwrite: unable to open file");
--- a/libinterp/octave-value/ov-java.cc	Fri Jun 12 11:39:35 2020 -0400
+++ b/libinterp/octave-value/ov-java.cc	Fri Jun 12 22:13:04 2020 +0200
@@ -254,9 +254,7 @@
 
     void read_java_opts (const std::string& filename)
     {
-      std::string ascii_fname = sys::get_ASCII_filename (filename);
-
-      std::ifstream js (ascii_fname.c_str ());
+      std::ifstream js = sys::ifstream (filename.c_str ());
 
       if (! js.bad () && ! js.fail ())
         {
@@ -376,9 +374,7 @@
 {
   std::string classpath;
 
-  std::string ascii_fname = octave::sys::get_ASCII_filename (filepath);
-
-  std::ifstream fs (ascii_fname.c_str ());
+  std::ifstream fs = octave::sys::ifstream (filepath.c_str ());
 
   if (! fs.bad () && ! fs.fail ())
     {
--- a/libinterp/parse-tree/oct-parse.yy	Fri Jun 12 11:39:35 2020 -0400
+++ b/libinterp/parse-tree/oct-parse.yy	Fri Jun 12 22:13:04 2020 +0200
@@ -4648,9 +4648,7 @@
   {
     // NAME should be an absolute file name and the file should exist.
 
-    std::string ascii_fname = sys::get_ASCII_filename (name);
-
-    std::ifstream fs (ascii_fname.c_str (), std::ios::in);
+    std::ifstream fs = sys::ifstream (name.c_str (), std::ios::in);
 
     std::string text;
 
--- a/liboctave/system/lo-sysdep.cc	Fri Jun 12 11:39:35 2020 -0400
+++ b/liboctave/system/lo-sysdep.cc	Fri Jun 12 22:13:04 2020 +0200
@@ -27,8 +27,6 @@
 #  include "config.h"
 #endif
 
-#include <string>
-
 #include "dir-ops.h"
 #include "file-ops.h"
 #include "lo-error.h"
@@ -350,6 +348,48 @@
 #endif
     }
 
+    std::fstream
+    fstream (const std::string& filename, const std::ios::openmode mode)
+    {
+#if defined (OCTAVE_USE_WINDOWS_API)
+
+      std::wstring wfilename = u8_to_wstring (filename);
+
+      return std::fstream (wfilename.c_str (), mode);
+
+#else
+      return std::fstream (filename.c_str (), mode);
+#endif
+    }
+
+    std::ifstream
+    ifstream (const std::string& filename, const std::ios::openmode mode)
+    {
+#if defined (OCTAVE_USE_WINDOWS_API)
+
+      std::wstring wfilename = u8_to_wstring (filename);
+
+      return std::ifstream (wfilename.c_str (), mode);
+
+#else
+      return std::ifstream (filename.c_str (), mode);
+#endif
+    }
+
+    std::ofstream
+    ofstream (const std::string& filename, const std::ios::openmode mode)
+    {
+#if defined (OCTAVE_USE_WINDOWS_API)
+
+      std::wstring wfilename = u8_to_wstring (filename);
+
+      return std::ofstream (wfilename.c_str (), mode);
+
+#else
+      return std::ofstream (filename.c_str (), mode);
+#endif
+    }
+
     void
     putenv_wrapper (const std::string& name, const std::string& value)
     {
--- a/liboctave/system/lo-sysdep.h	Fri Jun 12 11:39:35 2020 -0400
+++ b/liboctave/system/lo-sysdep.h	Fri Jun 12 22:13:04 2020 +0200
@@ -28,6 +28,7 @@
 
 #include "octave-config.h"
 
+#include <fstream>
 #include <string>
 
 #include <sys/types.h>
@@ -49,6 +50,16 @@
 
     extern std::FILE * fopen (const std::string& name, const std::string& mode);
 
+    extern std::fstream fstream (const std::string& name,
+                                 const std::ios::openmode mode =
+                                   std::ios::in | std::ios::out);
+
+    extern std::ifstream ifstream (const std::string& name,
+                                   const std::ios::openmode mode = std::ios::in);
+
+    extern std::ofstream ofstream (const std::string& name,
+                                   const std::ios::openmode mode = std::ios::out);
+
     extern void putenv_wrapper (const std::string& name,
                                 const std::string& value);
 
--- a/liboctave/util/cmd-hist.cc	Fri Jun 12 11:39:35 2020 -0400
+++ b/liboctave/util/cmd-hist.cc	Fri Jun 12 22:13:04 2020 +0200
@@ -37,6 +37,7 @@
 #include "cmd-hist.h"
 #include "file-ops.h"
 #include "lo-error.h"
+#include "lo-sysdep.h"
 #include "singleton-cleanup.h"
 #include "str-vec.h"
 
@@ -399,7 +400,7 @@
 
                     if (! fs)
                       {
-                        std::fstream tmp (f, std::ios::out);
+                        std::ofstream tmp = sys::ofstream (f, std::ios::out);
                         tmp.close ();
                       }
 
--- a/liboctave/util/file-info.cc	Fri Jun 12 11:39:35 2020 -0400
+++ b/liboctave/util/file-info.cc	Fri Jun 12 22:13:04 2020 +0200
@@ -83,9 +83,8 @@
 
     size_t sz = fs.size ();
 
-    std::string ascii_fname = sys::get_ASCII_filename (fname);
-
-    std::ifstream file (ascii_fname.c_str (), std::ios::in | std::ios::binary);
+    std::ifstream file = sys::ifstream (fname.c_str (),
+                                        std::ios::in | std::ios::binary);
 
     if (file)
       {
--- a/liboctave/util/url-transfer.cc	Fri Jun 12 11:39:35 2020 -0400
+++ b/liboctave/util/url-transfer.cc	Fri Jun 12 22:13:04 2020 +0200
@@ -121,8 +121,9 @@
               {
                 std::string realfile = target + directory + sep + sv(i);
 
-                std::ofstream ofile (realfile.c_str (),
-                                     std::ios::out | std::ios::binary);
+                std::ofstream ofile =
+                  sys::ofstream (realfile.c_str (),
+                                 std::ios::out | std::ios::binary);
 
                 if (! ofile.is_open ())
                   {
@@ -206,10 +207,9 @@
               else
                 {
                   // FIXME: Does ascii mode need to be flagged here?
-                  std::string ascii_fname = sys::get_ASCII_filename (realfile);
-
-                  std::ifstream ifile (ascii_fname.c_str (),
-                                       std::ios::in | std::ios::binary);
+                  std::ifstream ifile =
+                    sys::ifstream (realfile.c_str (),
+                                   std::ios::in | std::ios::binary);
 
                   if (! ifile.is_open ())
                     {
--- a/src/mkoctfile.in.cc	Fri Jun 12 11:39:35 2020 -0400
+++ b/src/mkoctfile.in.cc	Fri Jun 12 22:13:04 2020 +0200
@@ -61,6 +61,7 @@
 #  endif
 #else
 #  include "mkostemps-wrapper.h"
+#  include "uniconv-wrappers.h"
 #  include "unistd-wrappers.h"
 #  include "wait-wrappers.h"
 #endif
@@ -89,6 +90,14 @@
   return mkostemps (tmpl, suffixlen, 0);
 }
 
+static char *
+octave_u8_conv_to_encoding (const char *tocode, const uint8_t *src,
+                            size_t srclen, size_t *lengthp)
+{
+  // FIXME: Do we need to provide the conversion here?
+  return nullptr;
+}
+
 static int
 octave_unlink_wrapper (const char *nm)
 {
@@ -980,8 +989,33 @@
                + vars["CPPFLAGS"] + ' ' + vars["ALL_CFLAGS"] + ' '
                + incflags  + ' ' + defs + ' ' + quote_path (f));
 
+          // FIXME: Use wide character API for popen on Windows.
           FILE *fd = popen (cmd.c_str (), "r");
+
+#if defined (OCTAVE_USE_WINDOWS_API)
+          // FIXME: liboctinterp isn't linked in to mkoctfile.
+          // So we cannot use octave::sys::ofstream. Instead we fall back
+          // on using the functions available from libwrappers.
+          size_t srclen = dfile.length ();
+          const uint8_t *src = reinterpret_cast<const uint8_t *>
+                               (dfile.c_str ());
+
+          size_t length = 0;
+          wchar_t *wchar = reinterpret_cast<wchar_t *>
+                           (octave_u8_conv_to_encoding ("wchar_t", src, srclen,
+                                                        &length));
+
+          std::ofstream fo;
+          if (wchar != nullptr)
+            {
+              fo.open (wchar);
+              free (static_cast<void *> (wchar));
+            }
+          else
+            fo.open (dfile.c_str ());
+#else
           std::ofstream fo (dfile.c_str ());
+#endif
           size_t pos;
           while (! feof (fd))
             {
@@ -1014,8 +1048,33 @@
                + vars["CPPFLAGS"] + ' ' + vars["ALL_CXXFLAGS"] + ' '
                + incflags  + ' ' + defs + ' ' + quote_path (f));
 
+          // FIXME: Use wide character API for popen on Windows.
           FILE *fd = popen (cmd.c_str (), "r");
+
+#if defined (OCTAVE_USE_WINDOWS_API)
+          // FIXME: liboctinterp isn't linked in to mkoctfile.
+          // So we cannot use octave::sys::ofstream. Instead we fall back
+          // on using the functions available from libwrappers.
+          size_t srclen = dfile.length ();
+          const uint8_t *src = reinterpret_cast<const uint8_t *>
+                               (dfile.c_str ());
+
+          size_t length = 0;
+          wchar_t *wchar = reinterpret_cast<wchar_t *>
+                           (octave_u8_conv_to_encoding ("wchar_t", src, srclen,
+                                                        &length));
+
+          std::ofstream fo;
+          if (wchar != nullptr)
+            {
+              fo.open (wchar);
+              free (static_cast<void *> (wchar));
+            }
+          else
+            fo.open (dfile.c_str ());
+#else
           std::ofstream fo (dfile.c_str ());
+#endif
           size_t pos;
           while (! feof (fd))
             {