# HG changeset patch # User Rik # Date 1430254983 25200 # Node ID 64a2d4c87ecbac9264bee3059a1a3a6e23d646b5 # Parent bcf0a288aa6c858f69ce339bc773581e7a12f07a Don't save "warning: " prefix in lastwarn() message. * error.cc (vwarning): Save base_msg (without "warning: ") to Vlast_warning_message. * error.cc (error_1): Use std::string operators rather than strsave to strip "\n" from fmt string. Simpler syntax avoids having to delete [] memory created with new. * error.cc (warning_1): Strip trailing newline from fmt string as error_1 does. * fail.m: Fix input validation which allowed nonsensical second input with 3 args. Don't post-process warning or error messages from lastwarn or lasterr. Add BIST test for input validation. diff -r bcf0a288aa6c -r 64a2d4c87ecb libinterp/corefcn/error.cc --- a/libinterp/corefcn/error.cc Tue Apr 28 12:12:16 2015 -0400 +++ b/libinterp/corefcn/error.cc Tue Apr 28 14:03:03 2015 -0700 @@ -158,21 +158,22 @@ std::ostringstream output_buf; - if (name) - output_buf << name << ": "; - octave_vformat (output_buf, fmt, args); - output_buf << std::endl; - // FIXME: we really want to capture the message before it has all the // formatting goop attached to it. We probably also want just the // message, not the traceback information. - std::string msg_string = output_buf.str (); + std::string base_msg = output_buf.str (); + std::string msg_string; + + if (name) + msg_string = std::string (name) + ": "; + + msg_string += base_msg + "\n"; Vlast_warning_id = id; - Vlast_warning_message = msg_string; + Vlast_warning_message = base_msg; if (! Vquiet_warning) { @@ -337,33 +338,30 @@ { if (error_state != -2) { - if (fmt) + if (fmt && *fmt) { - if (*fmt) + size_t len = strlen (fmt); + + if (len > 0) { - size_t len = strlen (fmt); - - if (len > 0) + if (fmt[len - 1] == '\n') { - if (fmt[len - 1] == '\n') + if (len > 1) { - if (len > 1) - { - char *tmp_fmt = strsave (fmt); - tmp_fmt[len - 1] = '\0'; - verror (true, os, name, id, tmp_fmt, args, with_cfn); - delete [] tmp_fmt; - } + // Strip newline before issuing error + std::string tmp_fmt (fmt, len - 1); + verror (true, os, name, id, tmp_fmt.c_str (), + args, with_cfn); + } - error_state = -2; - } - else - { - verror (true, os, name, id, fmt, args, with_cfn); + error_state = -2; + } + else + { + verror (true, os, name, id, fmt, args, with_cfn); - if (! error_state) - error_state = 1; - } + if (! error_state) + error_state = 1; } } } @@ -634,13 +632,21 @@ } else if (warn_opt == 1) { - vwarning ("warning", id, fmt, args); + bool fmt_suppresses_backtrace = false; + size_t fmt_len = fmt ? strlen (fmt) : 0; + fmt_suppresses_backtrace = (fmt_len > 0 && fmt[fmt_len-1] == '\n'); + + if (fmt_suppresses_backtrace && fmt_len > 1) + { + // Strip newline before issuing warning + std::string tmp_fmt (fmt, fmt_len - 1); + vwarning ("warning", id, tmp_fmt.c_str (), args); + } + else + vwarning ("warning", id, fmt, args); bool in_user_code = octave_call_stack::caller_user_code () != 0; - bool fmt_suppresses_backtrace = false; - size_t fmt_len = fmt ? strlen (fmt) : 0; - fmt_suppresses_backtrace = (fmt_len > 0 && fmt[fmt_len-1] == '\n'); if (! fmt_suppresses_backtrace && in_user_code && Vbacktrace_on_warning && ! warning_state diff -r bcf0a288aa6c -r 64a2d4c87ecb scripts/testfun/fail.m --- a/scripts/testfun/fail.m Tue Apr 28 12:12:16 2015 -0400 +++ b/scripts/testfun/fail.m Tue Apr 28 14:03:03 2015 -0700 @@ -67,11 +67,20 @@ endif ## Parse input arguments - test_warning = (nargin > 1 && strcmp (pattern, "warning")); - if (nargin == 3) - pattern = warning_pattern; - elseif (nargin == 1 || (nargin == 2 && test_warning)) + test_warning = false; + if (nargin == 1) pattern = ""; + elseif (nargin == 2 && ! strcmp (pattern, "warning")) + ## Normal error test + elseif (nargin >= 2 && strcmp (pattern, "warning")) + test_warning = true; + if (nargin == 2) + pattern = ""; + else + pattern = warning_pattern; + endif + else + print_usage (); endif ## Match any nonempty message @@ -89,28 +98,24 @@ ## Clear old warnings. lastwarn (""); ## Make sure warnings are turned on. - state = warning ("query", "quiet"); + wstate = warning ("query", "quiet"); warning ("on", "quiet"); try evalin ("caller", [code ";"]); ## Retrieve new warnings. warn = lastwarn (); - warning (state.state, "quiet"); + warning (wstate.state, "quiet"); if (isempty (warn)) msg = sprintf ("expected warning <%s> but got none", pattern); else - ## Transform "warning: ...\n" to "...". - warn([1:9, end]) = []; if (! isempty (regexp (warn, pattern, "once"))) return; endif msg = sprintf ("expected warning <%s>\nbut got <%s>", pattern, warn); endif catch - warning (state.state, "quiet"); - err = lasterr; - ## Transform "error: ...\n", to "...". - err([1:6, end]) = []; + warning (wstate.state, "quiet"); + err = lasterr (); msg = sprintf ("expected warning <%s>\nbut got error <%s>", pattern, err); end_try_catch @@ -121,9 +126,6 @@ msg = sprintf ("expected error <%s> but got none", pattern); catch err = lasterr (); - if (strcmp (err(1:7), "error:")) - err([1:6, end]) = []; # transform "error: ...\n", to "..." - endif if (! isempty (regexp (err, pattern, "once"))) return; endif @@ -153,4 +155,5 @@ ## Test input validation %!error fail () %!error fail (1,2,3,4) +%!error fail (1, "nowarning", "foo")