Mercurial > octave
changeset 27279:1c8b20731af4
Convert encoding just before writing to stream (bug #55452).
* oct-stream.[cc,h] (printf): Don't convert format string separately.
* oct-stream.cc (do_print_conv): Pass on encoding to octave::format.
(do_printf): Convert strings to encoding.
* utils.[cc,h] (format): Add overload with encoding specifier.
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Sat, 09 Mar 2019 22:09:25 +0100 |
parents | 94d490815aa8 |
children | 8d30dc86e5d9 |
files | libinterp/corefcn/oct-stream.cc libinterp/corefcn/oct-stream.h libinterp/corefcn/utils.cc libinterp/corefcn/utils.h |
diffstat | 4 files changed, 61 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/oct-stream.cc Tue Mar 05 17:56:57 2019 +0100 +++ b/libinterp/corefcn/oct-stream.cc Sat Mar 09 22:09:25 2019 +0100 @@ -5571,23 +5571,24 @@ template <typename T> int - do_printf_conv (std::ostream& os, const char *fmt, int nsa, int sa_1, - int sa_2, T arg, const std::string& who) + do_printf_conv (std::ostream& os, const std::string& encoding, + const char *fmt, int nsa, int sa_1, int sa_2, T arg, + const std::string& who) { int retval = 0; switch (nsa) { case 2: - retval = format (os, fmt, sa_1, sa_2, arg); + retval = format (os, encoding, fmt, sa_1, sa_2, arg); break; case 1: - retval = format (os, fmt, sa_1, arg); + retval = format (os, encoding, fmt, sa_1, arg); break; case 0: - retval = format (os, fmt, arg); + retval = format (os, encoding, fmt, arg); break; default: @@ -5747,7 +5748,8 @@ tval = (lo_ieee_is_NA (dval) ? "NA" : "NaN"); } - retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2, tval, who); + retval += do_printf_conv (os, encoding (), tfmt.c_str (), nsa, sa_1, + sa_2, tval, who); } else { @@ -5766,8 +5768,8 @@ // Insert "long" modifier. tfmt.replace (tfmt.rfind (type), 1, llmod + type); - retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2, - tval.value (), who); + retval += do_printf_conv (os, encoding (), tfmt.c_str (), nsa, + sa_1, sa_2, tval.value (), who); } else { @@ -5775,7 +5777,7 @@ double dval = val.double_value (true); - retval += do_printf_conv (os, tfmt.c_str (), nsa, + retval += do_printf_conv (os, encoding (), tfmt.c_str (), nsa, sa_1, sa_2, dval, who); } break; @@ -5788,8 +5790,8 @@ // Insert "long" modifier. tfmt.replace (tfmt.rfind (type), 1, llmod + type); - retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2, - tval.value (), who); + retval += do_printf_conv (os, encoding (), tfmt.c_str (), nsa, + sa_1, sa_2, tval.value (), who); } else { @@ -5797,7 +5799,7 @@ double dval = val.double_value (true); - retval += do_printf_conv (os, tfmt.c_str (), nsa, + retval += do_printf_conv (os, encoding (), tfmt.c_str (), nsa, sa_1, sa_2, dval, who); } break; @@ -5807,8 +5809,8 @@ { double dval = val.double_value (true); - retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2, - dval, who); + retval += do_printf_conv (os, encoding (), tfmt.c_str (), nsa, + sa_1, sa_2, dval, who); } break; @@ -5878,12 +5880,18 @@ if (elt->type == '%') { - os << '%'; + if (encoding ().compare ("utf-8")) + os << string::u8_to_encoding (who, "%", encoding ()); + else + os << '%'; retval++; } else if (elt->args == 0 && ! elt->text.empty ()) { - os << elt->text; + if (encoding ().compare ("utf-8")) + os << string::u8_to_encoding (who, elt->text, encoding ()); + else + os << elt->text; retval += (elt->text.length ()); } else if (elt->type == 's' || elt->type == 'c') @@ -5938,13 +5946,10 @@ } int - base_stream::printf (std::string fmt, + base_stream::printf (const std::string& fmt, const octave_value_list& args, const std::string& who) { - if (encoding ().compare ("utf-8")) - fmt = string::u8_to_encoding (who, fmt, encoding ()); - printf_format_list fmt_list (fmt); if (fmt_list.num_conversions () == -1)
--- a/libinterp/corefcn/oct-stream.h Tue Mar 05 17:56:57 2019 +0100 +++ b/libinterp/corefcn/oct-stream.h Sat Mar 09 22:09:25 2019 +0100 @@ -235,7 +235,7 @@ int do_printf (printf_format_list& fmt_list, const octave_value_list& args, const std::string& who /* = "printf" */); - int printf (std::string fmt, const octave_value_list& args, + int printf (const std::string& fmt, const octave_value_list& args, const std::string& who /* = "printf" */); int puts (const std::string& s, const std::string& who /* = "puts" */);
--- a/libinterp/corefcn/utils.cc Tue Mar 05 17:56:57 2019 +0100 +++ b/libinterp/corefcn/utils.cc Sat Mar 09 22:09:25 2019 +0100 @@ -42,6 +42,7 @@ #include "oct-cmplx.h" #include "oct-env.h" #include "oct-locbuf.h" +#include "oct-string.h" #include "pathsearch.h" #include "quit.h" #include "str-vec.h" @@ -1236,6 +1237,33 @@ return s.length (); } + size_t format (std::ostream& os, const std::string& enc, const char *fmt, ...) + { + size_t retval; + + va_list args; + va_start (args, fmt); + + retval = vformat (os, enc, fmt, args); + + va_end (args); + + return retval; + } + + size_t vformat (std::ostream& os, const std::string& enc, const char *fmt, + va_list args) + { + std::string s = vasprintf (fmt, args); + + if (enc.compare ("utf-8")) + os << string::u8_to_encoding ("printf", s, enc); + else + os << s; + + return s.length (); + } + std::string vasprintf (const char *fmt, va_list args) { std::string retval;
--- a/libinterp/corefcn/utils.h Tue Mar 05 17:56:57 2019 +0100 +++ b/libinterp/corefcn/utils.h Sat Mar 09 22:09:25 2019 +0100 @@ -109,8 +109,15 @@ format (std::ostream& os, const char *fmt, ...); extern OCTINTERP_API size_t + format (std::ostream& os, const std::string& enc, const char *fmt, ...); + + extern OCTINTERP_API size_t vformat (std::ostream& os, const char *fmt, va_list args); + extern OCTINTERP_API size_t + vformat (std::ostream& os, const std::string& enc, + const char *fmt, va_list args); + extern OCTINTERP_API std::string vasprintf (const char *fmt, va_list args);