# HG changeset patch # User John W. Eaton # Date 1440619549 14400 # Node ID 44eb1102f8a8d3afba12e7a0ffeca490d67f5be3 # Parent 7fbba8c8efd5d919be9a7f05e7d7de78bd958fcf don't recycle scanf format string if all conversions are done (bug #45808) * oct-stream.cc, oct-stream.h (scanf_format_elt::special_conversion): New enum value, no_conversion. (scanf_format_list::next): If not cycling through the list, return dummy scanf_format_elt after list has been exhausted. (octave_base_stream::do_scanf): Only cycle through the format list more than once if there are conversions to make and the limit on the number of values to convert has not been reached. diff -r 7fbba8c8efd5 -r 44eb1102f8a8 libinterp/corefcn/oct-stream.cc --- a/libinterp/corefcn/oct-stream.cc Wed Aug 26 22:51:59 2015 +0200 +++ b/libinterp/corefcn/oct-stream.cc Wed Aug 26 16:05:49 2015 -0400 @@ -1603,11 +1603,19 @@ if (elt) { - if (! (elt->type == scanf_format_elt::whitespace_conversion - || elt->type == scanf_format_elt::literal_conversion - || elt->type == '%') - && max_conv > 0 && conversion_count == max_conv) + if (elt->type == scanf_format_elt::null + || (! (elt->type == scanf_format_elt::whitespace_conversion + || elt->type == scanf_format_elt::literal_conversion + || elt->type == '%') + && max_conv > 0 && conversion_count == max_conv)) { + // We are done, either because we have reached the end + // of the format string and are not cycling through + // the format again or because we've converted all the + // values that have been requested and the next format + // element is a conversion. Determine final array + // size and exit. + if (all_char_conv && one_elt_size_spec) { final_nr = 1; @@ -1859,7 +1867,16 @@ break; } else - elt = fmt_list.next (nconv > 0); + { + // Cycle through the format list more than once if we have + // some conversions to make and we haven't reached the + // limit on the number of values to convert (possibly + // because there is no specified limit). + + elt = fmt_list.next (nconv > 0 + && (max_conv == 0 + || conversion_count < max_conv)); + } } } diff -r 7fbba8c8efd5 -r 44eb1102f8a8 libinterp/corefcn/oct-stream.h --- a/libinterp/corefcn/oct-stream.h Wed Aug 26 22:51:59 2015 +0200 +++ b/libinterp/corefcn/oct-stream.h Wed Aug 26 16:05:49 2015 -0400 @@ -49,7 +49,8 @@ enum special_conversion { whitespace_conversion = 1, - literal_conversion = 2 + literal_conversion = 2, + null = 3 }; scanf_format_elt (const char *txt = 0, int w = 0, bool d = false, @@ -129,6 +130,9 @@ const scanf_format_elt *next (bool cycle = true) { + static scanf_format_elt dummy + (0, 0, false, scanf_format_elt::null, '\0', ""); + curr_idx++; if (curr_idx >= list.numel ()) @@ -136,8 +140,9 @@ if (cycle) curr_idx = 0; else - return 0; + return &dummy; } + return current (); }