Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Tom Tromey <tromey@redhat.com>
To: "Rob Quill" <rob.quill@gmail.com>
Cc: gdb-patches@sourceware.org
Subject: Re: New scope checking patch
Date: Wed, 30 Jul 2008 03:34:00 -0000	[thread overview]
Message-ID: <m3bq0g59md.fsf@fleche.redhat.com> (raw)
In-Reply-To: <baf6008d0807291404x255213b7id79efc6939d92eb1@mail.gmail.com> (Rob Quill's message of "Tue\, 29 Jul 2008 22\:04\:18 +0100")

>>>>> "Rob" == Rob Quill <rob.quill@gmail.com> writes:

Rob> Where can I find out about internal functions?

I've appended the patch.  It adds a new sort of value, which is an
internal function.  These are just like ordinary functions in an
expression but they run inside gdb -- not the inferior.  The user sees
them as convenience variables of "internal function" type.

This patch builds but, because it is divorced from the code that uses
it, I did not test it.  So, if you try it, let me know how it fails :)

BTW -- I noticed that with your patch, an expression using $in_scope
will not print properly.  That is because in_scope is turned into a
constant in the expression structure.


Thiago -- FYI, I took the patch from the python-patches branch,
deleted stuff relying on things not yet in cvs (command destructors
and Python), and then wrote comments and a ChangeLog entry.  You may
want the latter :)

Tom

b/gdb/ChangeLog:
2008-07-29  Tom Tromey  <tromey@redhat.com>

	* value.h (lookup_only_internalvar, create_internalvar,
	lookup_internalvar): Update.
	(internal_function_fn, add_internal_function,
	call_internal_function, value_internal_function_name): Declare.
	* value.c (struct internal_function): New struct.
	(functionlist): New global.
	(internal_fn_type): Likewise.
	(lookup_only_internalvar): Made argument const.
	(create_internalvar): Likewise.
	(lookup_internalvar): Likewise.
	(value_create_internal_function): New function.
	(value_internal_function_name): Likewise.
	(call_internal_function): Likewise.
	(function_command): Likewise.
	(add_internal_function): Likewise.
	(_initialize_values): Add the "function" command.  Initialize
	internal_fn_type.
	* valprint.c (value_check_printable): Handle
	TYPE_CODE_INTERNAL_FUNCTION.
	* gdbtypes.h (enum type_code) <TYPE_CODE_INTERNAL_FUNCTION>: New
	constant.
	* eval.c: (evaluate_subexp_standard) <OP_FUNCALL>: Handle
	TYPE_CODE_INTERNAL_FUNCTION.

projecttype:gdb
email:tromey@gcc.gnu.org
revision:edd41e881c9f658211f1ebc08126a0222488e3a4
configure:
make:
check:

diff --git a/gdb/eval.c b/gdb/eval.c
index bbd7539..7ee910f 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1293,6 +1293,9 @@ evaluate_subexp_standard (struct type *expect_type,
 	  else
 	    error (_("Expression of type other than \"Function returning ...\" used as function"));
 	}
+      if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_INTERNAL_FUNCTION)
+	return call_internal_function (argvec[0], nargs, argvec + 1);
+
       return call_function_by_hand (argvec[0], nargs, argvec + 1);
       /* pai: FIXME save value from call_function_by_hand, then adjust pc by adjust_fn_pc if +ve  */
 
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 7ef7d67..365707b 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -133,7 +133,10 @@ enum type_code
 
     TYPE_CODE_NAMESPACE,	/* C++ namespace.  */
 
-    TYPE_CODE_DECFLOAT		/* Decimal floating point.  */
+    TYPE_CODE_DECFLOAT,		/* Decimal floating point.  */
+
+    /* Internal function type.  */
+    TYPE_CODE_INTERNAL_FUNCTION
   };
 
 /* For now allow source to use TYPE_CODE_CLASS for C++ classes, as an
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 99c376f..617a3f4 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -259,6 +259,13 @@ value_check_printable (struct value *val, struct ui_file *stream)
       return 0;
     }
 
+  if (TYPE_CODE (value_type (val)) == TYPE_CODE_INTERNAL_FUNCTION)
+    {
+      fprintf_filtered (stream, _("<internal function %s>"),
+			value_internal_function_name (val));
+      return 0;
+    }
+
   return 1;
 }
 
diff --git a/gdb/value.c b/gdb/value.c
index b38bae0..93436e3 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -41,6 +41,24 @@
 
 void _initialize_values (void);
 
+/* Definition of a user function.  */
+struct internal_function
+{
+  /* The name of the function.  It is a bit odd to have this in the
+     function itself -- the user might use a differently-named
+     convenience variable to hold the function.  */
+  char *name;
+
+  /* The handler.  */
+  internal_function_fn handler;
+
+  /* User data for the handler.  */
+  void *cookie;
+};
+
+/* Command list holding internal functions.  */
+static struct cmd_list_element *functionlist;
+
 struct value
 {
   /* Type of value; either not an lval, or one of the various
@@ -203,6 +221,10 @@ struct value_history_chunk
 static struct value_history_chunk *value_history_chain;
 
 static int value_history_count;	/* Abs number of last entry stored */
+
+/* The type of internal functions.  */
+
+static struct type *internal_fn_type;
 \f
 /* List of all value objects currently allocated
    (except for those released by calls to release_value)
@@ -747,7 +769,7 @@ init_if_undefined_command (char* args, int from_tty)
    the return value is NULL.  */
 
 struct internalvar *
-lookup_only_internalvar (char *name)
+lookup_only_internalvar (const char *name)
 {
   struct internalvar *var;
 
@@ -763,7 +785,7 @@ lookup_only_internalvar (char *name)
    NAME should not normally include a dollar sign.  */
 
 struct internalvar *
-create_internalvar (char *name)
+create_internalvar (const char *name)
 {
   struct internalvar *var;
   var = (struct internalvar *) xmalloc (sizeof (struct internalvar));
@@ -784,7 +806,7 @@ create_internalvar (char *name)
    one is created, with a void value.  */
 
 struct internalvar *
-lookup_internalvar (char *name)
+lookup_internalvar (const char *name)
 {
   struct internalvar *var;
 
@@ -888,6 +910,81 @@ internalvar_name (struct internalvar *var)
   return var->name;
 }
 
+/* Create a value which represents an internal function.
+   NAME is the name of the function.
+   HANDLER is a pointer to a function which is called when this
+   internal function is invoked during expression evaluation.
+   COOKIE is a pointer which is passed verbatim to HANDLER.  */
+static struct value *
+value_create_internal_function (const char *name,
+				internal_function_fn handler,
+				void *cookie)
+{
+  struct value *result = allocate_value (internal_fn_type);
+  gdb_byte *addr = value_contents_writeable (result);
+  struct internal_function **fnp = (struct internal_function **) addr;
+  /* The internal_function object is leaked here -- to make it truly
+     deletable, we would have to reference count it and add special
+     code to value_free and value_copy.  */
+  struct internal_function *ifn = XNEW (struct internal_function);
+  ifn->name = xstrdup (name);
+  ifn->handler = handler;
+  ifn->cookie = cookie;
+  *fnp = ifn;
+  return result;
+}
+
+/* Return the name of the value VAL, which is assumed to be of
+   "internal function" type.  The result is not copied and should not
+   be freed or modified.  */
+char *
+value_internal_function_name (struct value *val)
+{
+  gdb_byte *addr = value_contents_writeable (val);
+  struct internal_function *ifn = * (struct internal_function **) addr;
+  return ifn->name;
+}
+
+/* Call an internal function.  FUNC is a value which is assumed to be
+   of "internal function" type.  ARGC is the number of arguments to
+   pass to it, and ARGV is a vector holding the arguments.  */
+struct value *
+call_internal_function (struct value *func, int argc, struct value **argv)
+{
+  gdb_byte *addr = value_contents_writeable (func);
+  struct internal_function *ifn = * (struct internal_function **) addr;
+  return (*ifn->handler) (ifn->cookie, argc, argv);
+}
+
+/* The 'function' command.  This does nothing -- it is just a
+   placeholder to let "help function NAME" work.  This is also used as
+   the implementation of the sub-command that is created when
+   registering an internal function.  */
+static void
+function_command (char *command, int from_tty)
+{
+  /* Do nothing.  */
+}
+
+/* Add a new internal function.  NAME is the name of the function; DOC
+   is a documentation string describing the function.  HANDLER is
+   called when the function is invoked.  COOKIE is an arbitrary
+   pointer which is passed to HANDLER and is intended for "user
+   data".  */
+void
+add_internal_function (const char *name, const char *doc,
+		       internal_function_fn handler,
+		       void *cookie)
+{
+  struct internalvar *var = lookup_internalvar (name);
+  struct value *fnval = value_create_internal_function (name, handler, cookie);
+  release_value (fnval);
+  set_internalvar (var, fnval);
+
+  add_cmd (xstrdup (name), no_class, function_command, (char *) doc,
+	   &functionlist);
+}
+
 /* Update VALUE before discarding OBJFILE.  COPIED_TYPES is used to
    prevent cycles / duplicates.  */
 
@@ -1780,4 +1877,13 @@ init-if-undefined VARIABLE = EXPRESSION\n\
 Set an internal VARIABLE to the result of the EXPRESSION if it does not\n\
 exist or does not contain a value.  The EXPRESSION is not evaluated if the\n\
 VARIABLE is already initialized."));
+
+  add_prefix_cmd ("function", no_class, function_command, _("\
+Placeholder command for showing help on convenience functions."),
+		  &functionlist, "function ", 0, &cmdlist);
+
+  internal_fn_type = alloc_type (NULL);
+  TYPE_CODE (internal_fn_type) = TYPE_CODE_INTERNAL_FUNCTION;
+  TYPE_LENGTH (internal_fn_type) = sizeof (struct internal_function *);
+  TYPE_NAME (internal_fn_type) = "<internal function>";
 }
diff --git a/gdb/value.h b/gdb/value.h
index 2aac9b2..bb597b2 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -451,11 +451,11 @@ extern void set_internalvar_component (struct internalvar *var,
 				       int bitpos, int bitsize,
 				       struct value *newvalue);
 
-extern struct internalvar *lookup_only_internalvar (char *name);
+extern struct internalvar *lookup_only_internalvar (const char *name);
 
-extern struct internalvar *create_internalvar (char *name);
+extern struct internalvar *create_internalvar (const char *name);
 
-extern struct internalvar *lookup_internalvar (char *name);
+extern struct internalvar *lookup_internalvar (const char *name);
 
 extern int value_equal (struct value *arg1, struct value *arg2);
 
@@ -570,4 +570,19 @@ extern struct value *value_allocate_space_in_inferior (int);
 extern struct value *value_of_local (const char *name, int complain);
 
 extern struct value * value_subscripted_rvalue (struct value *array, struct value *idx, int lowerbound);
+
+/* User function handler.  */
+
+typedef struct value *(*internal_function_fn) (void *cookie,
+					       int argc,
+					       struct value **argv);
+
+void add_internal_function (const char *name, const char *doc,
+			    internal_function_fn handler, void *cookie);
+
+struct value *call_internal_function (struct value *function,
+				      int argc, struct value **argv);
+
+char *value_internal_function_name (struct value *);
+
 #endif /* !defined (VALUE_H) */


  parent reply	other threads:[~2008-07-30  3:34 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-12 16:29 Rob Quill
2007-11-12 23:26 ` Michael Snyder
2008-01-10  1:00 ` Jim Blandy
2008-01-11  0:52   ` Rob Quill
2008-01-11 22:51     ` Jim Blandy
2008-01-14 23:07       ` Michael Snyder
2008-01-15 17:06         ` Jim Blandy
2008-01-17 19:32       ` Rob Quill
2008-01-17 20:15         ` Jim Blandy
2008-01-17 21:11           ` Rob Quill
2008-01-17 21:58             ` Jim Blandy
2008-01-17 23:40               ` Doug Evans
2008-01-18  1:31               ` Daniel Jacobowitz
2008-01-18  3:35               ` Rob Quill
2008-01-18 18:48                 ` Jim Blandy
2008-01-18 22:43                   ` Rob Quill
2008-01-19  0:38                     ` Jim Blandy
2008-01-30 13:11                       ` Rob Quill
2008-01-30 18:14                         ` Jim Blandy
2008-01-30 18:31                         ` Eli Zaretskii
2008-01-31  4:11                           ` Jim Blandy
2008-01-31  7:26                             ` Eli Zaretskii
2008-07-27 23:45                               ` Rob Quill
2008-07-28  3:18                                 ` Eli Zaretskii
2008-07-28 10:31                                   ` Rob Quill
2008-07-28 18:27                                     ` Eli Zaretskii
2008-07-29 20:31                                 ` Tom Tromey
2008-07-29 21:04                                   ` Rob Quill
2008-07-29 21:45                                     ` Tom Tromey
2008-07-29 22:53                                       ` Rob Quill
2008-07-30  3:34                                     ` Tom Tromey [this message]
2008-10-23 13:42                                       ` Convenience functions (was: Re: New scope checking patch) Daniel Jacobowitz
2008-10-23 15:17                                         ` Convenience functions Tom Tromey
2008-10-23 15:22                                           ` Daniel Jacobowitz
2008-10-23 15:26                                             ` Tom Tromey
2008-10-23 19:14                                             ` Tom Tromey
2008-10-24 12:53                                               ` Eli Zaretskii
2008-11-04 21:37                                         ` Convenience functions (was: Re: New scope checking patch) Thiago Jung Bauermann
2008-11-04 22:23                                           ` Daniel Jacobowitz
2008-11-04 22:43                                             ` Convenience functions Tom Tromey
2008-01-31  7:52                             ` New scope checking patch Michael Snyder
2008-01-19  1:35                     ` Michael Snyder

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m3bq0g59md.fsf@fleche.redhat.com \
    --to=tromey@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=rob.quill@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox