This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH/RFA] Introduce new $_isvoid() convenience function


Hi,

Based on the discussion at:

<https://sourceware.org/ml/gdb-patches/2013-09/msg00301.html>
<https://sourceware.org/ml/gdb-patches/2013-09/msg00383.html>

I am submitting this patch for appreciation.  It adds a new convenience
function called $_isvoid, whose only purpose is (duh) to check whether a
convenience variable is void or not.  This became necessary because the
new convenience variable $_exitsignal (not yet approved) has a mutual
exclusive behavior with $_exitcode, i.e., when one is "defined" (i.e.,
non-void), the other is cleared (i.e., becomes void).  Doug wanted a way
to identify which variable to use, and checking for voidness is the
obvious solution.

It is worth mentioning that my first attempt, after a conversation with
Doug, was to actually implement a new $_isdefined() convenience
function.  I would do that (for convenience variables) by calling
lookup_only_internalvar.  However, I found a few problems:

- Whenever I called $_isdefined ($variable), $variable became defined
  (with a void value), and $_isdefined always returned true.

- Then, I tried to implement $_isdefined ("variable"), and do the "$" +
  "variable" inside GDB, thus making it impossible for GDB to create the
  convenience variable.  However, it was hard to extract the string
  without having to mess with values and their idiossincrasies.
  Therefore, I decided to abandon this attempt (specially because I
  didn't want to spend too much time struggling with it).

Anyway, after talking to Doug again we decided that it would be easier
to implement $_isvoid, and this will probably help in cases like
<http://stackoverflow.com/questions/3744554/testing-if-a-gdb-convenience-variable-is-defined>.

I wrote a NEWS entry for it, and some new lines on the documentation.
I'd appreciate if you could review that.

OK to apply?

Thanks,

-- 
Sergio

gdb/
2013-09-12  Sergio Durigan Junior  <sergiodj@redhat.com>

	* NEWS: Mention new convenience function $_isvoid.
	* value.c (isvoid_internal_fn): New function.
	(_initialize_values): Add new convenience function $_isvoid.

gdb/doc/
2013-09-12  Sergio Durigan Junior  <sergiodj@redhat.com>

	* gdb.texinfo (Convenience Functions): Mention new convenience
	function $_isvoid.

gdb/testsuite/
2013-09-12  Sergio Durigan Junior  <sergiodj@redhat.com>

	* gdb.base/gdbvars.exp (test_convenience_functions): New
	function.  Call it.

diff --git a/gdb/NEWS b/gdb/NEWS
index ad97f6f..eff90de 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,9 @@
 
 *** Changes since GDB 7.6
 
+* New convenience function "$_isvoid", to check whether a convenience
+  variable is void.
+
 * The "maintenance print objfiles" command now takes an optional regexp.
 
 * The "catch syscall" command now works on arm*-linux* targets.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index b6ba239..a056691 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -9829,6 +9829,18 @@ Returns the length of string @var{str}.
 
 @end table
 
+These functions do not require @value{GDBN} to be configured with
+@code{Python} support, which means that they are always available.
+
+@table @code
+
+@item $_isvoid (@code{$var})
+@findex $_isvoid@r{, convenience function}
+Return one if the convenience variable @code{$var} is void.  Otherwise
+it returns zero.
+
+@end table
+
 @value{GDBN} provides the ability to list and get help on
 convenience functions.
 
diff --git a/gdb/testsuite/gdb.base/gdbvars.exp b/gdb/testsuite/gdb.base/gdbvars.exp
index 23a6758..79c90b6 100644
--- a/gdb/testsuite/gdb.base/gdbvars.exp
+++ b/gdb/testsuite/gdb.base/gdbvars.exp
@@ -54,6 +54,23 @@ proc test_convenience_variables {} {
 	"Print contents of uninitialized convenience variable"
 }
 
+proc test_convenience_functions {} {
+    gdb_test "print \$_isvoid" " = <internal function _isvoid>" \
+	"Print internal function \$_isvoid"
+
+    gdb_test "print \$isvoid_foo" " = void" \
+	"Print void convenience variable"
+
+    gdb_test "print \$_isvoid (\$isvoid_foo)" " = 1" \
+	"Check whether void convenience variable is void"
+
+    gdb_test_no_output "set \$isvoid_foo = 1" \
+	"Set void convenience variable to 1"
+
+    gdb_test "print \$_isvoid (\$isvoid_foo)" " = 0" \
+	"Check whether non-void convenience variable is void"
+}
+
 proc test_value_history {} {
     global gdb_prompt
 
@@ -114,4 +131,5 @@ gdb_test_no_output "set print sevenbit-strings"
 
 test_value_history
 test_convenience_variables
+test_convenience_functions
 test_with_program
diff --git a/gdb/value.c b/gdb/value.c
index 42a8d2f..e8eea17 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -3584,6 +3584,32 @@ value_fetch_lazy (struct value *val)
   return 0;
 }
 
+/* Implementation of the convenience function $_isvoid.
+
+   This function only works for checking whether other convenience
+   variables are void or not.  */
+
+static struct value *
+isvoid_internal_fn (struct gdbarch *gdbarch,
+		    const struct language_defn *language,
+		    void *cookie, int argc, struct value **argv)
+{
+  struct value *v;
+  int ret;
+
+  if (argc != 1)
+    error (_("You must provide one parameter for $_isvoid."));
+
+  v = argv[0];
+
+  if (VALUE_LVAL (v) != lval_internalvar)
+    error (_("$_isvoid can only be used for convenience variables."));
+
+  ret = TYPE_CODE (value_type (v)) == TYPE_CODE_VOID;
+
+  return value_from_longest (builtin_type (gdbarch)->builtin_int, ret);
+}
+
 void
 _initialize_values (void)
 {
@@ -3616,4 +3642,10 @@ VARIABLE is already initialized."));
   add_prefix_cmd ("function", no_class, function_command, _("\
 Placeholder command for showing help on convenience functions."),
 		  &functionlist, "function ", 0, &cmdlist);
+
+  add_internal_function ("_isvoid", _("\
+Check whether a convenience variable is void.\n\
+Usage: $_isvoid ($variable)\n\
+Return 1 if the convenience variable is void, zero otherwise."),
+			 isvoid_internal_fn, NULL);
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]