diff --git a/libinterp/corefcn/oct-stream.cc b/libinterp/corefcn/oct-stream.cc --- a/libinterp/corefcn/oct-stream.cc +++ b/libinterp/corefcn/oct-stream.cc @@ -2186,6 +2186,13 @@ public: // Get the current value as an int and advance the internal pointer. int int_value (void); + // Get the current value as a character and advance the internal pointer. + char char_value (void); + + // Determine if the current value is a string. Do not advance + // internal pointer. + bool is_string (void); + // Get the current value as a string and advance the internal pointer. std::string string_value (void); @@ -2295,6 +2302,41 @@ printf_value_cache::int_value (void) return retval; } +char +printf_value_cache::char_value (void) +{ + int retval = 0; + + octave_value val = get_next_value (); + + if (! error_state) + { + std::string sval = val.string_value (); + + if (! error_state) + retval = sval[0]; + } + + return retval; +} + +bool +printf_value_cache::is_string (void) +{ + bool retval = false; + + if (exhausted ()) + curr_state = conversion_error; + else + { + octave_value tval = values (val_idx); + + retval = tval.is_string (); + } + + return retval; +} + std::string printf_value_cache::string_value (void) { @@ -2378,7 +2420,9 @@ ok_for_signed_int_conv (const octave_val { uint64_t limit = std::numeric_limits::max (); - if (val.is_integer_type ()) + if (val.is_string ()) + return false; + else if (val.is_integer_type ()) { if (val.is_uint64_type ()) { @@ -2392,7 +2436,7 @@ ok_for_signed_int_conv (const octave_val } else { - double dval = val.double_value (); + double dval = val.double_value (true); if (dval == xround (dval) && dval <= limit) return true; @@ -2404,7 +2448,9 @@ ok_for_signed_int_conv (const octave_val static bool ok_for_unsigned_int_conv (const octave_value& val) { - if (val.is_integer_type ()) + if (val.is_string ()) + return false; + else if (val.is_integer_type ()) { // Easier than dispatching here... @@ -2415,7 +2461,7 @@ ok_for_unsigned_int_conv (const octave_v } else { - double dval = val.double_value (); + double dval = val.double_value (true); uint64_t limit = std::numeric_limits::max (); @@ -2532,7 +2578,7 @@ octave_base_stream::do_numeric_printf_co { std::string tfmt = switch_to_g_format (elt); - double dval = val.double_value (); + double dval = val.double_value (true); if (! error_state) retval += do_printf_conv (os, tfmt.c_str (), nsa, @@ -2543,7 +2589,7 @@ octave_base_stream::do_numeric_printf_co case 'f': case 'e': case 'E': case 'g': case 'G': { - double dval = val.double_value (); + double dval = val.double_value (true); if (! error_state) retval += do_printf_conv (os, fmt, nsa, sa_1, sa_2, dval, who); @@ -2634,6 +2680,16 @@ octave_base_stream::do_printf (printf_fo else break; } + else if (elt->type == 'c' && val_cache.is_string ()) + { + char c = val_cache.char_value (); + + if (val_cache) + retval += do_printf_conv (os, elt->text, nsa, sa_1, + sa_2, c, who); + else + break; + } else { octave_value val = val_cache.get_next_value ();