Mercurial > octave
changeset 29492:be4b78fb4411
Replace Unicode conversion functions from gnulib with STL functions.
* liboctave/system/lo-sysdep.cc (u8_to_wstring, u8_from_wstring): Use C++11
functions to convert between UTF-8 and the Unicode encoding that is used for
"wstring"s.
(putenv_wrapper): Use "u8_to_wstring" instead of "u8_to_wchar".
* liboctave/system/oct-env.cc (do_get_user_config_directory,
do_get_user_data_directory): Use "u8_from_wstring" instead of "u8_from_wchar".
* libinterp/corefcn/sysdep.cc (popen): Use "u8_to_wstring" instead of
"u8_to_wchar".
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Fri, 02 Apr 2021 19:28:07 +0200 |
parents | 747f592e2001 |
children | de40b395b9c3 |
files | libinterp/corefcn/sysdep.cc liboctave/system/lo-sysdep.cc liboctave/system/oct-env.cc |
diffstat | 3 files changed, 55 insertions(+), 69 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/sysdep.cc Mon Apr 05 09:15:48 2021 -0700 +++ b/libinterp/corefcn/sysdep.cc Fri Apr 02 19:28:07 2021 +0200 @@ -698,24 +698,14 @@ FILE * popen (const char *command, const char *mode) { #if defined (__MINGW32__) || defined (_MSC_VER) - wchar_t *wcommand = u8_to_wchar (command); - wchar_t *wmode = u8_to_wchar (mode); - - unwind_action free_memory ([=] () - { - ::free (wcommand); - ::free (wmode); - }); + std::wstring wcommand = octave::sys::u8_to_wstring (command); + std::wstring wmode = octave::sys::u8_to_wstring (mode); - if (wmode && wmode[0] && ! wmode[1]) - { - // Use binary mode on Windows if unspecified - wchar_t tmode[3] = {wmode[0], L'b', L'\0'}; + // Use binary mode on Windows if unspecified + if (wmode.length () < 2) + wmode += L'b'; - return _wpopen (wcommand, tmode); - } - else - return _wpopen (wcommand, wmode); + return _wpopen (wcommand.c_str (), wmode.c_str ()); #else return ::popen (command, mode); #endif
--- a/liboctave/system/lo-sysdep.cc Mon Apr 05 09:15:48 2021 -0700 +++ b/liboctave/system/lo-sysdep.cc Fri Apr 02 19:28:07 2021 +0200 @@ -28,6 +28,8 @@ #endif #include <cstdlib> +#include <locale> +#include <codecvt> #include "dir-ops.h" #include "file-ops.h" @@ -35,7 +37,6 @@ #include "lo-sysdep.h" #include "localcharset-wrapper.h" #include "putenv-wrapper.h" -#include "uniconv-wrappers.h" #include "unistd-wrappers.h" #include "unsetenv-wrapper.h" @@ -46,6 +47,7 @@ # include "filepos-wrappers.h" # include "lo-hash.h" # include "oct-locbuf.h" +# include "uniconv-wrappers.h" # include "unwind-prot.h" #endif @@ -425,33 +427,34 @@ void putenv_wrapper (const std::string& name, const std::string& value) { - // This function was adapted from xputenv from Karl Berry's kpathsearch - // library. - // FIXME: make this do the right thing if we don't have a SMART_PUTENV. + std::string new_env = name + "=" + value; - int new_len = name.length () + value.length () + 2; - - // FIXME: This leaks memory, but so would a call to setenv. + // FIXME: The malloc leaks memory, but so would a call to setenv. // Short of extreme measures to track memory, altering the environment // always leaks memory, but the saving grace is that the leaks are small. - char *new_item = static_cast<char *> (std::malloc (new_len)); - - if (new_item) - sprintf (new_item, "%s=%s", name.c_str (), value.c_str ()); - // As far as I can see there's no way to distinguish between the // various errors; putenv doesn't have errno values. #if defined (OCTAVE_USE_WINDOWS_API) - wchar_t *wnew_item = u8_to_wchar (new_item); + std::wstring new_wenv = u8_to_wstring (new_env); + + int len = (new_wenv.length () + 1) * sizeof (wchar_t); + + wchar_t *new_item = static_cast<wchar_t *> (std::malloc (len)); + + wcscpy (new_item, new_wenv.c_str()); - // free new_item, but leak wnew_item (see above) - unwind_action free_new_item ([=] () { std::free (new_item); }); + if (_wputenv (new_item) < 0) + (*current_liboctave_error_handler) + ("putenv (%s) failed", new_env.c_str()); +#else + int len = new_env.length () + 1; - if (_wputenv (wnew_item) < 0) - (*current_liboctave_error_handler) ("putenv (%s) failed", new_item); -#else + char *new_item = static_cast<char *> (std::malloc (len)); + + std::strcpy (new_item, new_env.c_str()); + if (octave_putenv_wrapper (new_item) < 0) (*current_liboctave_error_handler) ("putenv (%s) failed", new_item); #endif @@ -486,20 +489,21 @@ std::wstring u8_to_wstring (const std::string& utf8_string) { - size_t srclen = utf8_string.length (); - const uint8_t *src = reinterpret_cast<const uint8_t *> - (utf8_string.c_str ()); - - size_t length = 0; - wchar_t *wchar = reinterpret_cast<wchar_t *> - (octave_u8_conv_to_encoding ("wchar_t", src, srclen, - &length)); + // convert multibyte UTF-8 string to wide character string + static std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> + wchar_conv; std::wstring retval = L""; - if (wchar != nullptr) + + try { - retval = std::wstring (wchar, length / sizeof (wchar_t)); - free (static_cast<void *> (wchar)); + retval = wchar_conv.from_bytes (utf8_string); + } + catch (const std::range_error& e) + { + // What to do in case of error? + // error ("u8_to_wstring: converting from UTF-8 to wchar_t: %s", + // e.what ()); } return retval; @@ -508,19 +512,21 @@ std::string u8_from_wstring (const std::wstring& wchar_string) { - size_t srclen = wchar_string.length () * sizeof (wchar_t); - const char *src = reinterpret_cast<const char *> (wchar_string.c_str ()); - - size_t length = 0; - char *mbchar = reinterpret_cast<char *> - (octave_u8_conv_from_encoding ("wchar_t", src, srclen, - &length)); + // convert wide character string to multibyte UTF-8 string + static std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> + wchar_conv; std::string retval = ""; - if (mbchar != nullptr) + + try { - retval = std::string (mbchar, length); - free (static_cast<void *> (mbchar)); + retval = wchar_conv.to_bytes (wchar_string); + } + catch (const std::range_error& e) + { + // What to do in case of error? + // error ("u8_from_wstring: converting from wchar_t to UTF-8: %s", + // e.what ()); } return retval;
--- a/liboctave/system/oct-env.cc Mon Apr 05 09:15:48 2021 -0700 +++ b/liboctave/system/oct-env.cc Fri Apr 02 19:28:07 2021 +0200 @@ -61,8 +61,6 @@ #include "unistd-wrappers.h" #if defined (OCTAVE_USE_WINDOWS_API) -# include "uniconv-wrappers.h" - # include <windows.h> # include <shlobj.h> #endif @@ -254,18 +252,14 @@ wchar_t path[MAX_PATH+1]; if (SHGetFolderPathW (nullptr, CSIDL_APPDATA | CSIDL_FLAG_DONT_VERIFY, nullptr, SHGFP_TYPE_CURRENT, path) == S_OK) - { - char *app_data = u8_from_wchar (path); - cfg_dir = app_data; - free (app_data); - } + cfg_dir = u8_from_wstring (path); #else cfg_dir = do_getenv ("XDG_CONFIG_HOME"); +#endif if (cfg_dir.empty ()) cfg_dir = do_get_home_directory () + sys::file_ops::dir_sep_str () + ".config"; -#endif return cfg_dir; } @@ -279,18 +273,14 @@ wchar_t path[MAX_PATH+1]; if (SHGetFolderPathW (nullptr, CSIDL_APPDATA | CSIDL_FLAG_DONT_VERIFY, nullptr, SHGFP_TYPE_CURRENT, path) == S_OK) - { - char *app_data = u8_from_wchar (path); - data_dir = app_data; - free (app_data); - } + data_dir = u8_from_wstring (path); #else data_dir = do_getenv ("XDG_DATA_HOME"); +#endif if (data_dir.empty ()) data_dir = do_get_home_directory () + sys::file_ops::dir_sep_str () + ".local" + sys::file_ops::dir_sep_str () + "share"; -#endif return data_dir; }