# HG changeset patch # User jwe # Date 949099454 0 # Node ID 2c7524ffdbf54381a68d94d3a909333b4422880a # Parent fc5eac74640d661ad79203db3aa6e7c9c3ec9546 [project @ 2000-01-28 22:44:13 by jwe] diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,16 @@ 2000-01-28 John W. Eaton + * pt-except.cc (do_catch_code): Don't do anything special for + tree_return_command::returning, or tree_break_command::breaking. + + * error.cc (vwarning): New function. + (warning): Use it instead of calling verror. + + * oct-stream.cc (octave_base_stream::oscanf): + Result is now always nconv+1 elements. Return count of successful + conversions in last element. + * file-io.cc (Ffscanf, Fsscanf, Fscanf): Fix doc string. + * pt-except.cc (do_catch_code): Unwind-protect buffer_error_messages. Be sure to run all unwind-protects before returning. (tree_try_catch_command::eval): Add do_catch_code cleanup function diff --git a/src/error.cc b/src/error.cc --- a/src/error.cc +++ b/src/error.cc @@ -57,6 +57,29 @@ // The message buffer ostrstream *error_message_buffer = 0; +// Warning messages are never buffered. +// XXX FIXME XXX -- we should provide another way to turn them off... + +static void +vwarning (const char *name, const char *fmt, va_list args) +{ + flush_octave_stdout (); + + ostrstream output_buf; + + if (name) + { + octave_diary << name << ": "; + cerr << name << ": "; + } + + octave_diary.vform (fmt, args); + cerr.vform (fmt, args); + + octave_diary << endl; + cerr << endl; +} + static void verror (const char *name, const char *fmt, va_list args) { @@ -175,7 +198,7 @@ va_list args; va_start (args, fmt); warning_state = 1; - verror ("warning", fmt, args); + vwarning ("warning", fmt, args); va_end (args); } diff --git a/src/file-io.cc b/src/file-io.cc --- a/src/file-io.cc +++ b/src/file-io.cc @@ -764,7 +764,7 @@ DEFUN (fscanf, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {[@var{val}, @var{count}] =} fscanf (@var{fid}, @var{template}, @var{size})\n\ -@deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}] = } fscanf (@var{fid}, @var{template}, \"C\")\n\ +@deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}] = } fscanf (@var{fid}, @var{template}, \"C\")\n\ In the first form, read from @var{fid} according to @var{template},\n\ returning the result in the matrix @var{val}.\n\ \n\ @@ -800,7 +800,8 @@ In the second form, read from @var{fid} according to @var{template},\n\ with each conversion specifier in @var{template} corresponding to a\n\ single scalar return value. This form is more `C-like', and also\n\ -compatible with previous versions of Octave.\n\ +compatible with previous versions of Octave. The number of successful\n\ +conversions is returned in @var{count}\n\ @end deftypefn") { octave_value_list retval; @@ -865,7 +866,7 @@ DEFUN (sscanf, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {[@var{val}, @var{count}] =} sscanf (@var{string}, @var{template}, @var{size})\n\ -@deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}] = } sscanf (@var{string}, @var{template}, \"C\")\n\ +@deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}] = } sscanf (@var{string}, @var{template}, \"C\")\n\ This is like @code{fscanf}, except that the characters are taken from the\n\ string @var{string} instead of from a stream. Reaching the end of the\n\ string is treated as an end-of-file condition.\n\ @@ -957,7 +958,7 @@ DEFUN (scanf, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {[@var{val}, @var{count}] =} scanf (@var{template}, @var{size})\n\ -@deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}] = } scanf (@var{template}, \"C\")\n\ +@deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}]] = } scanf (@var{template}, \"C\")\n\ This is equivalent to calling @code{fscanf} with @var{fid} = @code{stdin}.\n\ \n\ It is currently not useful to call @code{scanf} in interactive\n\ diff --git a/src/oct-stream.cc b/src/oct-stream.cc --- a/src/oct-stream.cc +++ b/src/oct-stream.cc @@ -1822,7 +1822,7 @@ int len = fmt_list.length (); - retval.resize (nconv, Matrix ()); + retval.resize (nconv+1, Matrix ()); const scanf_format_elt *elt = fmt_list.first (); @@ -1849,7 +1849,7 @@ } } - retval.resize (num_values); + retval (nconv) = static_cast (num_values); if (! quit) { diff --git a/src/pt-except.cc b/src/pt-except.cc --- a/src/pt-except.cc +++ b/src/pt-except.cc @@ -65,38 +65,9 @@ unwind_protect::add (clear_global_error_variable, 0); - // Similarly, if we have seen a return or break statement, allow all - // the catch code to run before returning or handling the break. - // We don't have to worry about continue statements because they can - // only occur in loops. - - unwind_protect_int (tree_return_command::returning); - tree_return_command::returning = 0; - - unwind_protect_int (tree_break_command::breaking); - tree_break_command::breaking = 0; - if (list) list->eval (); - // This is the one for breaking. (The unwind_protects are popped - // off the stack in the reverse of the order they are pushed on). - - // XXX FIXME XXX -- inside a try-catch, should break work like - // a return, or just jump to the end of the try_catch block? - // The following code makes it just jump to the end of the block. - - unwind_protect::run (); - if (tree_break_command::breaking) - tree_break_command::breaking--; - - // This is the one for returning. - - if (tree_return_command::returning) - unwind_protect::discard (); - else - unwind_protect::run (); - unwind_protect::run_frame ("do_catch_code"); } @@ -174,23 +145,43 @@ if (list) list->eval (); - // This is the one for breaking. (The unwind_protects are popped - // off the stack in the reverse of the order they are pushed on). - - // XXX FIXME XXX -- inside an unwind_protect, should break work like - // a return, or just jump to the end of the unwind_protect block? - // The following code makes it just jump to the end of the block. + // The unwind_protects are popped off the stack in the reverse of + // the order they are pushed on. - unwind_protect::run (); - if (tree_break_command::breaking) - tree_break_command::breaking--; + // XXX FIXME XXX -- these statements say that if we see a break or + // return statement in the cleanup block, that we want to use the + // new value of the breaking or returning flag instead of restoring + // the previous value. Is that the right thing to do? I think so. + // Consider the case of + // + // function foo () + // unwind_protect + // stderr << "1: this should always be executed\n"; + // break; + // stderr << "1: this should never be executed\n"; + // unwind_protect_cleanup + // stderr << "2: this should always be executed\n"; + // return; + // stderr << "2: this should never be executed\n"; + // end_unwind_protect + // endfunction + // + // If we reset the value of the breaking flag, both the returning + // flag and the breaking flag will be set, and we shouldn't have + // both. So, use the most recent one. If there is no return or + // break in the cleanup block, the values should be reset to + // whatever they were when the cleanup block was entered. - // This is the one for returning. - - if (tree_return_command::returning) - unwind_protect::discard (); + if (tree_break_command::breaking || tree_return_command::returning) + { + unwind_protect::discard (); + unwind_protect::discard (); + } else - unwind_protect::run (); + { + unwind_protect::run (); + unwind_protect::run (); + } // We don't want to ignore errors that occur in the cleanup code, so // if an error is encountered there, leave error_state alone.