Mercurial > hg > octave-lyh
changeset 14558:0c9c85e702ca
better compatibility for error/warning message IDs and format specifiers
* error.cc (maybe_extract_message_id): New function.
(Ferror, Fwarning): Use it to check for and extract message ID and
format string.
(handle_message): New arg, HAVE_FMT. Use it to determine whether to
call sprintf. Change all callers.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 12 Apr 2012 16:48:54 -0400 |
parents | e8e86ae3abbc |
children | 90c51d8797cc |
files | src/error.cc |
diffstat | 1 files changed, 69 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- a/src/error.cc +++ b/src/error.cc @@ -764,7 +764,7 @@ static std::string handle_message (error_fun f, const char *id, const char *msg, - const octave_value_list& args) + const octave_value_list& args, bool have_fmt) { std::string retval; @@ -776,7 +776,7 @@ { octave_value arg; - if (nargin > 1) + if (have_fmt) { octave_value_list tmp = Fsprintf (args, 1); arg = tmp(0); @@ -962,6 +962,56 @@ return retval; } +// Determine whether the first argument to error or warning function +// should be handled as the message identifier or as the format string. + +static bool +maybe_extract_message_id (const std::string& caller, + const octave_value_list& args, + octave_value_list& nargs, + std::string& id) +{ + nargs = args; + id = std::string (); + + int nargin = args.length (); + + bool have_fmt = nargin > 1; + + if (nargin > 0) + { + std::string arg1 = args(0).string_value (); + + if (! error_state) + { + // For compatibility with Matlab, an identifier must contain + // ':', but not at the beginning or the end, and it must not + // contain '%' (even if it is not a valid conversion operator). + + if (arg1.find ('%') == std::string::npos + && arg1.find (':') != std::string::npos + && arg1[0] != ':' + && arg1[arg1.length()-1] != ':') + { + if (nargin > 1) + { + id = arg1; + + nargs.resize (nargin-1); + + for (int i = 1; i < nargin; i++) + nargs(i-1) = args(i); + } + else + nargs(0) = "call to " + caller + + " with message identifier requires message"; + } + } + } + + return have_fmt; +} + DEFUN (error, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} error (@var{template}, @dots{})\n\ @@ -1031,26 +1081,9 @@ print_usage (); else { - if (nargin > 1) - { - std::string arg1 = args(0).string_value (); - - if (! error_state) - { - if (arg1.find ('%') == std::string::npos) - { - id = arg1; + bool have_fmt = false; - nargs.resize (nargin-1); - - for (int i = 1; i < nargin; i++) - nargs(i-1) = args(i); - } - } - else - return retval; - } - else if (nargin == 1 && args(0).is_map ()) + if (nargin == 1 && args(0).is_map ()) { // empty struct is not an error. return and resume calling function. if (args(0).is_empty ()) @@ -1084,8 +1117,16 @@ // structure, but that will require some more significant // surgery on handle_message, error_with_id, etc. } + else + { + have_fmt = maybe_extract_message_id ("error", args, nargs, id); - handle_message (error_with_id, id.c_str (), "unspecified error", nargs); + if (error_state) + return retval; + } + + handle_message (error_with_id, id.c_str (), "unspecified error", + nargs, have_fmt); } return retval; @@ -1399,30 +1440,16 @@ std::string id; - if (nargin > 1) - { - std::string arg1 = args(0).string_value (); - - if (! error_state) - { - if (arg1.find ('%') == std::string::npos) - { - id = arg1; + bool have_fmt = maybe_extract_message_id ("warning", args, nargs, id); - nargs.resize (nargin-1); - - for (int i = 1; i < nargin; i++) - nargs(i-1) = args(i); - } - } - else - return retval; - } + if (error_state) + return retval; std::string prev_msg = Vlast_warning_message; std::string curr_msg = handle_message (warning_with_id, id.c_str (), - "unspecified warning", nargs); + "unspecified warning", nargs, + have_fmt); if (nargout > 0) retval = prev_msg; @@ -1765,7 +1792,7 @@ @end deftypefn") { octave_value_list retval; - handle_message (usage_with_id, "", "unknown", args); + handle_message (usage_with_id, "", "unknown", args, true); return retval; }