changeset 9753:892e2aa7bc75

improve error messages by auto-prepending current function name
author Jaroslav Hajek <highegg@gmail.com>
date Thu, 22 Oct 2009 08:56:58 +0200
parents 51c21837686f
children 4219e5cf773d
files src/ChangeLog src/error.cc src/error.h src/octave.cc src/ov-base.cc src/ov.cc
diffstat 6 files changed, 87 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Thu Oct 22 20:25:08 2009 -0700
+++ b/src/ChangeLog	Thu Oct 22 08:56:58 2009 +0200
@@ -1,3 +1,18 @@
+2009-10-22  Jaroslav Hajek  <highegg@gmail.com>
+
+	* error.cc (verror (bool, std::ostream&, ..., bool)): Add optional
+	with_cfn flag. If specified, prepend current function name (unless
+	already there).
+	(error_1): Accept with_cfn flag and pass it on.
+	(error_2): Ditto.
+	(verror_with_cfn, error_with_cfn, error_with_id_cfn,
+	verror_with_id_cfn): New functions.
+	* error.h: Declare them.
+	* octave.cc (lo_error_handler): Call verror_with_cfn.
+	* ov-base.cc (INT_CONV_METHOD): Call error_with_cfn.
+	* ov.cc (octave_value::int_vector_value,
+	octave_idx_type_vector_value): Call error_with_cfn.
+
 2009-10-21  Rik <octave@nomad.inbox5.com>
 
 	* variables.cc: Correct use of deftypefnx for who and whos
--- a/src/error.cc	Thu Oct 22 20:25:08 2009 -0700
+++ b/src/error.cc	Thu Oct 22 08:56:58 2009 +0200
@@ -204,7 +204,8 @@
 
 static void
 verror (bool save_last_error, std::ostream& os,
-	const char *name, const char *id, const char *fmt, va_list args)
+	const char *name, const char *id, const char *fmt, va_list args,
+        bool with_cfn = false)
 {
   if (discard_error_messages)
     return;
@@ -232,6 +233,28 @@
   if (name)
     msg_string += std::string (name) + ": ";
 
+  // If with_fcn is specified, we'll attempt to prefix the message with the name
+  // of the current executing function. But we'll do so only if:
+  // 1. the name is not empty (anonymous function)
+  // 2. it is not already there (including the following colon)
+  if (with_cfn)
+    {
+      octave_function *curfcn = octave_call_stack::current ();
+      if (curfcn)
+        {
+          std::string cfn = curfcn->name ();
+          if (! cfn.empty ())
+            {
+              cfn += ':';
+              if (cfn.length () > base_msg.length ()
+                 || base_msg.compare (0, cfn.length (), cfn) != 0)
+                {
+                  msg_string += cfn + ' ';
+                }
+            }
+        }
+    }
+
   msg_string += base_msg + "\n";
 
   if (! error_state && save_last_error)
@@ -275,7 +298,7 @@
 
 static void
 error_1 (std::ostream& os, const char *name, const char *id,
-	 const char *fmt, va_list args)
+	 const char *fmt, va_list args, bool with_cfn = false)
 {
   if (error_state != -2)
     {
@@ -293,7 +316,7 @@
 			{
 			  char *tmp_fmt = strsave (fmt);
 			  tmp_fmt[len - 1] = '\0';
-			  verror (true, os, name, id, tmp_fmt, args);
+			  verror (true, os, name, id, tmp_fmt, args, with_cfn);
 			  delete [] tmp_fmt;
 			}
 
@@ -301,7 +324,7 @@
 		    }
 		  else
 		    {
-		      verror (true, os, name, id, fmt, args);
+		      verror (true, os, name, id, fmt, args, with_cfn);
 
 		      if (! error_state)
 			error_state = 1;
@@ -453,11 +476,11 @@
 }
 
 static void
-error_2 (const char *id, const char *fmt, va_list args)
+error_2 (const char *id, const char *fmt, va_list args, bool with_cfn = false)
 {
   int init_state = error_state;
 
-  error_1 (std::cerr, "error", id, fmt, args);
+  error_1 (std::cerr, "error", id, fmt, args, with_cfn);
 
   if ((interactive || forced_interactive)
       && Vdebug_on_error && init_state == 0
@@ -492,6 +515,21 @@
 }
 
 void
+verror_with_cfn (const char *fmt, va_list args)
+{
+  error_2 ("", fmt, args, true);
+}
+
+void
+error_with_cfn (const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  verror_with_cfn (fmt, args);
+  va_end (args);
+}
+
+void
 verror_with_id (const char *id, const char *fmt, va_list args)
 {
   error_2 (id, fmt, args);
@@ -506,6 +544,21 @@
   va_end (args);
 }
 
+void
+verror_with_id_cfn (const char *id, const char *fmt, va_list args)
+{
+  error_2 (id, fmt, args, true);
+}
+
+void
+error_with_id_cfn (const char *id, const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  verror_with_id_cfn (id, fmt, args);
+  va_end (args);
+}
+
 static int
 check_state (const std::string& state)
 {
--- a/src/error.h	Thu Oct 22 20:25:08 2009 -0700
+++ b/src/error.h	Thu Oct 22 08:56:58 2009 +0200
@@ -47,6 +47,9 @@
 extern OCTINTERP_API void verror (const char *fmt, va_list args);
 extern OCTINTERP_API void error (const char *fmt, ...);
 
+extern OCTINTERP_API void verror_with_cfn (const char *fmt, va_list args);
+extern OCTINTERP_API void error_with_cfn (const char *fmt, ...);
+
 extern OCTINTERP_API void vparse_error (const char *fmt, va_list args);
 extern OCTINTERP_API void parse_error (const char *fmt, ...);
 
@@ -75,6 +78,12 @@
 error_with_id (const char *id, const char *fmt, ...);
 
 extern OCTINTERP_API void
+verror_with_id_cfn (const char *id, const char *fmt, va_list args);
+
+extern OCTINTERP_API void
+error_with_id_cfn (const char *id, const char *fmt, ...);
+
+extern OCTINTERP_API void
 vparse_error_with_id (const char *id, const char *fmt, va_list args);
 
 extern OCTINTERP_API void
--- a/src/octave.cc	Thu Oct 22 20:25:08 2009 -0700
+++ b/src/octave.cc	Thu Oct 22 08:56:58 2009 +0200
@@ -552,7 +552,7 @@
 {
   va_list args;
   va_start (args, fmt);
-  verror (fmt, args);
+  verror_with_cfn (fmt, args);
   va_end (args);
 
   octave_throw_execution_exception ();
--- a/src/ov-base.cc	Thu Oct 22 20:25:08 2009 -0700
+++ b/src/ov-base.cc	Thu Oct 22 08:56:58 2009 +0200
@@ -395,7 +395,7 @@
     if (! error_state) \
       { \
 	if (require_int && D_NINT (d) != d) \
-	  error ("conversion of %g to " #T " value failed", d); \
+	  error_with_cfn ("conversion of %g to " #T " value failed", d); \
 	else if (d < MIN_LIMIT) \
 	  retval = MIN_LIMIT; \
 	else if (d > MAX_LIMIT) \
--- a/src/ov.cc	Thu Oct 22 20:25:08 2009 -0700
+++ b/src/ov.cc	Thu Oct 22 08:56:58 2009 +0200
@@ -1594,7 +1594,7 @@
                     retval.xelem (i) = v;
                   else
                     {
-                      error ("conversion to integer value failed");
+                      error_with_cfn ("conversion to integer value failed");
                       break;
                     }
                 }
@@ -1676,7 +1676,7 @@
                     retval.xelem (i) = v;
                   else
                     {
-                      error ("conversion to integer value failed");
+                      error_with_cfn ("conversion to integer value failed");
                       break;
                     }
                 }