gdb/
authorThiago Jung Bauermann <bauerman@br.ibm.com>
Fri, 6 Feb 2009 21:33:59 +0000 (21:33 +0000)
committerThiago Jung Bauermann <bauerman@br.ibm.com>
Fri, 6 Feb 2009 21:33:59 +0000 (21:33 +0000)
2009-02-06  Tom Tromey  <tromey@redhat.com>

* Makefile.in (SUBDIR_PYTHON_OBS): Add python-cmd.o.
(SUBDIR_PYTHON_SRCS): Add python-cmd.c.
(python-cmd.o): New target.
* cli/cli-decode.c (set_cmd_completer): Add self parameter to
completer prototype.
(add_cmd): Initialize destroyer member of cmd_list_element. Use
make_symbol_completion_list_fn as completer.
(delete_cmd): Call destroyer if one is set.
* cli/cli-decode.h (cmd_list_element): Add cmd parameter to
completer member.  Add destroyer member.
(set_cmd_completer): Add self parameter to
completer prototype.
* command.h (set_cmd_completer): Add cmd parameter to
completer prototype.
* completer.c (noop_completer, filename_completer,
location_completer, expression_completer, command_completer): Adapt
to new completer prototype.
(complete_line_internal): Pass new parameter to completer function.
* completer.h (noop_completer, filename_completer,
location_completer, expression_completer, command_completer): Adapt
prototypes to new completer prototype.
* interps.c (interpreter_completer): Adapt to new completer
prototype.
* python/python-cmd.c: New file.
* python/python-internal.h (gdbpy_initialize_commands): Add
prototype.
(gdbpy_doc_cst): Add forward declaration.
* python/python.c (gdbpy_doc_cst): Declare.
(_initialize_python): Call gdbpy_initialize_commands.  Initialize
gdbpy_doc_cst.
* symtab.c (make_symbol_completion_list_fn): New function.
* symtab.h (make_symbol_completion_list_fn): Add prototype.

gdb/doc/
2009-02-06  Tom Tromey  <tromey@redhat.com>

* gdb.texinfo (Python API): Add entry for Commands In Python.
(Commands In Python): New node.

gdb/testsuite/
2009-02-06  Thiago Jung Bauermann  <bauerman@br.ibm.com>

* gdb.python/python-cmd.exp: New file.

17 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/NEWS
gdb/cli/cli-decode.c
gdb/cli/cli-decode.h
gdb/command.h
gdb/completer.c
gdb/completer.h
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/interps.c
gdb/python/python-cmd.c [new file with mode: 0644]
gdb/python/python-internal.h
gdb/python/python.c
gdb/symtab.c
gdb/symtab.h
gdb/testsuite/ChangeLog

index 6038287..0f28a82 100644 (file)
@@ -1,3 +1,38 @@
+2009-02-06  Tom Tromey  <tromey@redhat.com>
+
+       * Makefile.in (SUBDIR_PYTHON_OBS): Add python-cmd.o.
+       (SUBDIR_PYTHON_SRCS): Add python-cmd.c.
+       (python-cmd.o): New target.
+       * cli/cli-decode.c (set_cmd_completer): Add self parameter to
+       completer prototype.
+       (add_cmd): Initialize destroyer member of cmd_list_element. Use
+       make_symbol_completion_list_fn as completer.
+       (delete_cmd): Call destroyer if one is set.
+       * cli/cli-decode.h (cmd_list_element): Add cmd parameter to
+       completer member.  Add destroyer member.
+       (set_cmd_completer): Add self parameter to
+       completer prototype.
+       * command.h (set_cmd_completer): Add cmd parameter to
+       completer prototype.
+       * completer.c (noop_completer, filename_completer,
+       location_completer, expression_completer, command_completer): Adapt
+       to new completer prototype.
+       (complete_line_internal): Pass new parameter to completer function.
+       * completer.h (noop_completer, filename_completer,
+       location_completer, expression_completer, command_completer): Adapt
+       prototypes to new completer prototype.
+       * interps.c (interpreter_completer): Adapt to new completer
+       prototype.
+       * python/python-cmd.c: New file.
+       * python/python-internal.h (gdbpy_initialize_commands): Add
+       prototype.
+       (gdbpy_doc_cst): Add forward declaration.
+       * python/python.c (gdbpy_doc_cst): Declare.
+       (_initialize_python): Call gdbpy_initialize_commands.  Initialize
+       gdbpy_doc_cst.
+       * symtab.c (make_symbol_completion_list_fn): New function.
+       * symtab.h (make_symbol_completion_list_fn): Add prototype.
+
 2009-02-06  Pedro Alves  <pedro@codesourcery.com>
 
        * target.c (target_get_osdata): Check for equal or higher than
 2009-02-06  Pedro Alves  <pedro@codesourcery.com>
 
        * target.c (target_get_osdata): Check for equal or higher than
index 6a4f77d..7400702 100644 (file)
@@ -270,10 +270,12 @@ SUBDIR_TUI_CFLAGS= \
 #
 SUBDIR_PYTHON_OBS = \
        python.o \
 #
 SUBDIR_PYTHON_OBS = \
        python.o \
+       python-cmd.o \
        python-utils.o \
        python-value.o
 SUBDIR_PYTHON_SRCS = \
        python/python.c \
        python-utils.o \
        python-value.o
 SUBDIR_PYTHON_SRCS = \
        python/python.c \
+       python/python-cmd.c \
        python/python-utils.c \
        python/python-value.c
 SUBDIR_PYTHON_DEPS =
        python/python-utils.c \
        python/python-value.c
 SUBDIR_PYTHON_DEPS =
@@ -1836,6 +1838,10 @@ python.o: $(srcdir)/python/python.c
        $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python.c
        $(POSTCOMPILE)
 
        $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python.c
        $(POSTCOMPILE)
 
+python-cmd.o: $(srcdir)/python/python-cmd.c
+       $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-cmd.c
+       $(POSTCOMPILE)
+
 python-utils.o: $(srcdir)/python/python-utils.c
        $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-utils.c
        $(POSTCOMPILE)
 python-utils.o: $(srcdir)/python/python-utils.c
        $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-utils.c
        $(POSTCOMPILE)
index a85caeb..d1abf0c 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -96,6 +96,8 @@ are treated as the standard definitions, regardless of context.
   GDB now has support for scripting using Python.  Whether this is
   available is determined at configure time.
 
   GDB now has support for scripting using Python.  Whether this is
   available is determined at configure time.
 
+  New GDB commands can now be written in Python.
+
 * Ada tasking support
 
   Ada tasks can now be inspected in GDB. The following commands have
 * Ada tasking support
 
   Ada tasks can now be inspected in GDB. The following commands have
index 556c027..8760ebf 100644 (file)
@@ -132,7 +132,8 @@ cmd_type (struct cmd_list_element *cmd)
 
 void
 set_cmd_completer (struct cmd_list_element *cmd,
 
 void
 set_cmd_completer (struct cmd_list_element *cmd,
-                  char **(*completer) (char *text, char *word))
+                  char **(*completer) (struct cmd_list_element *self,
+                                       char *text, char *word))
 {
   cmd->completer = completer; /* Ok.  */
 }
 {
   cmd->completer = completer; /* Ok.  */
 }
@@ -207,7 +208,8 @@ add_cmd (char *name, enum command_class class, void (*fun) (char *, int),
   c->prefixname = NULL;
   c->allow_unknown = 0;
   c->abbrev_flag = 0;
   c->prefixname = NULL;
   c->allow_unknown = 0;
   c->abbrev_flag = 0;
-  set_cmd_completer (c, make_symbol_completion_list);
+  set_cmd_completer (c, make_symbol_completion_list_fn);
+  c->destroyer = NULL;
   c->type = not_set_cmd;
   c->var = NULL;
   c->var_type = var_boolean;
   c->type = not_set_cmd;
   c->var = NULL;
   c->var_type = var_boolean;
@@ -688,6 +690,8 @@ delete_cmd (char *name, struct cmd_list_element **list,
     {
       if (strcmp (iter->name, name) == 0)
        {
     {
       if (strcmp (iter->name, name) == 0)
        {
+         if (iter->destroyer)
+           iter->destroyer (iter, iter->context);
          if (iter->hookee_pre)
            iter->hookee_pre->hook_pre = 0;
          *prehook = iter->hook_pre;
          if (iter->hookee_pre)
            iter->hookee_pre->hook_pre = 0;
          *prehook = iter->hook_pre;
index 56ea9bf..26ca2f7 100644 (file)
@@ -167,7 +167,12 @@ struct cmd_list_element
        returned relative to this position.  For example, suppose TEXT is "foo"
        and we want to complete to "foobar".  If WORD is "oo", return
        "oobar"; if WORD is "baz/foo", return "baz/foobar".  */
        returned relative to this position.  For example, suppose TEXT is "foo"
        and we want to complete to "foobar".  If WORD is "oo", return
        "oobar"; if WORD is "baz/foo", return "baz/foobar".  */
-    char **(*completer) (char *text, char *word);
+    char **(*completer) (struct cmd_list_element *cmd, char *text, char *word);
+
+    /* Destruction routine for this command.  If non-NULL, this is
+       called when this command instance is destroyed.  This may be
+       used to finalize the CONTEXT field, if needed.  */
+    void (*destroyer) (struct cmd_list_element *self, void *context);
 
     /* Type of "set" or "show" command (or SET_NOT_SET if not "set"
        or "show").  */
 
     /* Type of "set" or "show" command (or SET_NOT_SET if not "set"
        or "show").  */
@@ -242,7 +247,8 @@ extern void set_cmd_sfunc (struct cmd_list_element *cmd,
                                          struct cmd_list_element * c));
 
 extern void set_cmd_completer (struct cmd_list_element *cmd,
                                          struct cmd_list_element * c));
 
 extern void set_cmd_completer (struct cmd_list_element *cmd,
-                              char **(*completer) (char *text, char *word));
+                              char **(*completer) (struct cmd_list_element *self,
+                                                   char *text, char *word));
 
 /* HACK: cagney/2002-02-23: Code, mostly in tracepoints.c, grubs
    around in cmd objects to test the value of the commands sfunc().  */
 
 /* HACK: cagney/2002-02-23: Code, mostly in tracepoints.c, grubs
    around in cmd objects to test the value of the commands sfunc().  */
index b3f7013..bed615c 100644 (file)
@@ -138,7 +138,8 @@ extern void set_cmd_sfunc (struct cmd_list_element *cmd,
                           cmd_sfunc_ftype *sfunc);
 
 extern void set_cmd_completer (struct cmd_list_element *cmd,
                           cmd_sfunc_ftype *sfunc);
 
 extern void set_cmd_completer (struct cmd_list_element *cmd,
-                              char **(*completer) (char *text, char *word));
+                              char **(*completer) (struct cmd_list_element *cmd,
+                                                   char *text, char *word));
 
 /* HACK: cagney/2002-02-23: Code, mostly in tracepoints.c, grubs
    around in cmd objects to test the value of the commands sfunc().  */
 
 /* HACK: cagney/2002-02-23: Code, mostly in tracepoints.c, grubs
    around in cmd objects to test the value of the commands sfunc().  */
index 298cdd0..43fcf7a 100644 (file)
@@ -105,14 +105,14 @@ readline_line_completion_function (const char *text, int matches)
 /* This can be used for functions which don't want to complete on symbols
    but don't want to complete on anything else either.  */
 char **
 /* This can be used for functions which don't want to complete on symbols
    but don't want to complete on anything else either.  */
 char **
-noop_completer (char *text, char *prefix)
+noop_completer (struct cmd_list_element *ignore, char *text, char *prefix)
 {
   return NULL;
 }
 
 /* Complete on filenames.  */
 char **
 {
   return NULL;
 }
 
 /* Complete on filenames.  */
 char **
-filename_completer (char *text, char *word)
+filename_completer (struct cmd_list_element *ignore, char *text, char *word)
 {
   int subsequent_name;
   char **return_val;
 {
   int subsequent_name;
   char **return_val;
@@ -195,7 +195,7 @@ filename_completer (char *text, char *word)
 
    This is intended to be used in commands that set breakpoints etc.  */
 char **
 
    This is intended to be used in commands that set breakpoints etc.  */
 char **
-location_completer (char *text, char *word)
+location_completer (struct cmd_list_element *ignore, char *text, char *word)
 {
   int n_syms = 0, n_files = 0;
   char ** fn_list = NULL;
 {
   int n_syms = 0, n_files = 0;
   char ** fn_list = NULL;
@@ -412,7 +412,7 @@ add_struct_fields (struct type *type, int *nextp, char **output,
    names, but some language parsers also have support for completing
    field names.  */
 char **
    names, but some language parsers also have support for completing
    field names.  */
 char **
-expression_completer (char *text, char *word)
+expression_completer (struct cmd_list_element *ignore, char *text, char *word)
 {
   struct type *type;
   char *fieldname, *p;
 {
   struct type *type;
   char *fieldname, *p;
@@ -456,7 +456,7 @@ expression_completer (char *text, char *word)
     ;
 
   /* Not ideal but it is what we used to do before... */
     ;
 
   /* Not ideal but it is what we used to do before... */
-  return location_completer (p, word);
+  return location_completer (ignore, p, word);
 }
 
 /* Here are some useful test cases for completion.  FIXME: These should
 }
 
 /* Here are some useful test cases for completion.  FIXME: These should
@@ -651,7 +651,7 @@ complete_line_internal (const char *text, char *line_buffer, int point,
                           p--)
                        ;
                    }
                           p--)
                        ;
                    }
-                 list = (*c->completer) (p, word);
+                 list = (*c->completer) (c, p, word);
                }
            }
          else
                }
            }
          else
@@ -719,7 +719,7 @@ complete_line_internal (const char *text, char *line_buffer, int point,
                       p--)
                    ;
                }
                       p--)
                    ;
                }
-             list = (*c->completer) (p, word);
+             list = (*c->completer) (c, p, word);
            }
        }
     }
            }
        }
     }
@@ -737,7 +737,7 @@ complete_line (const char *text, char *line_buffer, int point)
 
 /* Complete on command names.  Used by "help".  */
 char **
 
 /* Complete on command names.  Used by "help".  */
 char **
-command_completer (char *text, char *word)
+command_completer (struct cmd_list_element *ignore, char *text, char *word)
 {
   return complete_line_internal (word, text, strlen (text), 1);
 }
 {
   return complete_line_internal (word, text, strlen (text), 1);
 }
index da1c381..6adbf1b 100644 (file)
@@ -21,15 +21,15 @@ extern char **complete_line (const char *text, char *line_buffer, int point);
 
 extern char *readline_line_completion_function (const char *text, int matches);
 
 
 extern char *readline_line_completion_function (const char *text, int matches);
 
-extern char **noop_completer (char *, char *);
+extern char **noop_completer (struct cmd_list_element *, char *, char *);
 
 
-extern char **filename_completer (char *, char *);
+extern char **filename_completer (struct cmd_list_element *, char *, char *);
 
 
-extern char **expression_completer (char *, char *);
+extern char **expression_completer (struct cmd_list_element *, char *, char *);
 
 
-extern char **location_completer (char *, char *);
+extern char **location_completer (struct cmd_list_element *, char *, char *);
 
 
-extern char **command_completer (char *, char *);
+extern char **command_completer (struct cmd_list_element *, char *, char *);
 
 extern char *get_gdb_completer_quote_characters (void);
 
 
 extern char *get_gdb_completer_quote_characters (void);
 
index 0f5363c..98502db 100644 (file)
@@ -1,3 +1,8 @@
+2009-02-06  Tom Tromey  <tromey@redhat.com>
+
+       * gdb.texinfo (Python API): Add entry for Commands In Python.
+       (Commands In Python): New node.
+
 2009-02-05  Tom Tromey  <tromey@redhat.com>
 
        * gdb.texinfo (Values From Inferior): Document Value.string.
 2009-02-05  Tom Tromey  <tromey@redhat.com>
 
        * gdb.texinfo (Values From Inferior): Document Value.string.
index a2ed0b8..354b888 100644 (file)
@@ -18064,6 +18064,7 @@ situation, a Python @code{KeyboardInterrupt} exception is thrown.
 * Basic Python::                Basic Python Functions.
 * Exception Handling::
 * Values From Inferior::
 * Basic Python::                Basic Python Functions.
 * Exception Handling::
 * Values From Inferior::
+* Commands In Python::          Implementing new commands in Python.
 @end menu
 
 @node Basic Python
 @end menu
 
 @node Basic Python
@@ -18246,6 +18247,259 @@ The optional @var{errors} argument is the same as the corresponding
 argument to Python's @code{string.decode} method.
 @end defmethod
 
 argument to Python's @code{string.decode} method.
 @end defmethod
 
+@node Commands In Python
+@subsubsection Commands In Python
+
+@cindex commands in python
+@cindex python commands
+@tindex Command
+@tindex gdb.Command
+You can implement new @value{GDBN} CLI commands in Python.  A CLI
+command is implemented using an instance of the @code{gdb.Command}
+class, most commonly using a subclass.
+
+@defmethod Command __init__ name @var{command-class} @r{[}@var{completer-class} @var{prefix}@r{]}
+The object initializer for @code{Command} registers the new command
+with @value{GDBN}.  This initializer is normally invoked from the
+subclass' own @code{__init__} method.
+
+@var{name} is the name of the command.  If @var{name} consists of
+multiple words, then the initial words are looked for as prefix
+commands.  In this case, if one of the prefix commands does not exist,
+an exception is raised.
+
+There is no support for multi-line commands.
+
+@var{command-class} should be one of the @samp{COMMAND_} constants
+defined below.  This argument tells @value{GDBN} how to categorize the
+new command in the help system.
+
+@var{completer-class} is an optional argument.  If given, it should be
+one of the @samp{COMPLETE_} constants defined below.  This argument
+tells @value{GDBN} how to perform completion for this command.  If not
+given, @value{GDBN} will attempt to complete using the object's
+@code{complete} method (see below); if no such method is found, an
+error will occur when completion is attempted.
+
+@var{prefix} is an optional argument.  If @code{True}, then the new
+command is a prefix command; sub-commands of this command may be
+registered.
+
+The help text for the new command is taken from the Python
+documentation string for the command's class, if there is one.  If no
+documentation string is provided, the default value ``This command is
+not documented.'' is used.
+@end defmethod
+
+@defmethod Command dont_repeat
+By default, a @value{GDBN} command is repeated when the user enters a
+blank line at the command prompt.  A command can suppress this
+behavior by invoking the @code{dont_repeat} method.  This is similar
+to the user command @code{dont-repeat}, see @ref{Define, dont-repeat}.
+@end defmethod
+
+@defmethod Command invoke argument from_tty
+This method is called by @value{GDBN} when this command is invoked.
+
+@var{argument} is a string.  It is the argument to the command, after
+leading and trailing whitespace has been stripped.
+
+@var{from_tty} is a boolean argument.  When true, this means that the
+command was entered by the user at the terminal; when false it means
+that the command came from elsewhere.
+
+If this method throws an exception, it is turned into a @value{GDBN}
+@code{error} call.  Otherwise, the return value is ignored.
+@end defmethod
+
+@defmethod Command complete text word
+This method is called by @value{GDBN} when the user attempts
+completion on this command.  All forms of completion are handled by
+this method, that is, the @key{TAB} and @key{M-?} key bindings, and
+the @code{complete} command.
+
+The arguments @var{text} and @var{word} are both strings.  @var{text}
+holds the complete command line up to the cursor's location.
+@var{word} holds the last word of the command line; this is computed
+using a word-breaking heuristic.
+
+The @code{complete} method can return several values:
+@itemize @bullet
+@item
+If the return value is a sequence, the contents of the sequence are
+used as the completions.  It is up to @code{complete} to ensure that the
+contents actually do complete the word.  A zero-length sequence is
+allowed, it means that there were no completions available.  Only
+string elements of the sequence are used; other elements in the
+sequence are ignored.
+
+@item
+If the return value is one of the @samp{COMPLETE_} constants defined
+below, then the corresponding @value{GDBN}-internal completion
+function is invoked, and its result is used.
+
+@item
+All other results are treated as though there were no available
+completions.
+@end itemize
+@end defmethod
+
+
+When a new command is registered, it must be declared as a member of
+some general class of commands.  This is used to classify top-level
+commands in the on-line help system; note that prefix commands are not
+listed under their own category but rather that of their top-level
+command.  The available classifications are represented by constants
+defined in the @code{gdb} module:
+
+@table @code
+@findex COMMAND_NONE
+@findex gdb.COMMAND_NONE
+@item COMMAND_NONE
+The command does not belong to any particular class.  A command in
+this category will not be displayed in any of the help categories.
+
+@findex COMMAND_RUNNING
+@findex gdb.COMMAND_RUNNING
+@item COMMAND_RUN
+The command is related to running the inferior.  For example,
+@code{start}, @code{step}, and @code{continue} are in this category.
+Type @code{help running} at the @value{GDBN} prompt to see a list of
+commands in this category.
+
+@findex COMMAND_DATA
+@findex gdb.COMMAND_DATA
+@item COMMAND_VARS
+The command is related to data or variables.  For example,
+@code{call}, @code{find}, and @code{print} are in this category.  Type
+@code{help data} at the @value{GDBN} prompt to see a list of commands
+in this category.
+
+@findex COMMAND_STACK
+@findex gdb.COMMAND_STACK
+@item COMMAND_STACK
+The command has to do with manipulation of the stack.  For example,
+@code{backtrace}, @code{frame}, and @code{return} are in this
+category.  Type @code{help stack} at the @value{GDBN} prompt to see a
+list of commands in this category.
+
+@findex COMMAND_FILES
+@findex gdb.COMMAND_FILES
+@item COMMAND_FILES
+This class is used for file-related commands.  For example,
+@code{file}, @code{list} and @code{section} are in this category.
+Type @code{help files} at the @value{GDBN} prompt to see a list of
+commands in this category.
+
+@findex COMMAND_SUPPORT
+@findex gdb.COMMAND_SUPPORT
+@item COMMAND_SUPPORT
+This should be used for ``support facilities'', generally meaning
+things that are useful to the user when interacting with @value{GDBN},
+but not related to the state of the inferior.  For example,
+@code{help}, @code{make}, and @code{shell} are in this category.  Type
+@code{help support} at the @value{GDBN} prompt to see a list of
+commands in this category.
+
+@findex COMMAND_STATUS
+@findex gdb.COMMAND_STATUS
+@item COMMAND_INFO
+The command is an @samp{info}-related command, that is, related to the
+state of @value{GDBN} itself.  For example, @code{info}, @code{macro},
+and @code{show} are in this category.  Type @code{help status} at the
+@value{GDBN} prompt to see a list of commands in this category.
+
+@findex COMMAND_BREAKPOINTS
+@findex gdb.COMMAND_BREAKPOINTS
+@item COMMAND_BREAKPOINT
+The command has to do with breakpoints.  For example, @code{break},
+@code{clear}, and @code{delete} are in this category.  Type @code{help
+breakpoints} at the @value{GDBN} prompt to see a list of commands in
+this category.
+
+@findex COMMAND_TRACEPOINTS
+@findex gdb.COMMAND_TRACEPOINTS
+@item COMMAND_TRACE
+The command has to do with tracepoints.  For example, @code{trace},
+@code{actions}, and @code{tfind} are in this category.  Type
+@code{help tracepoints} at the @value{GDBN} prompt to see a list of
+commands in this category.
+
+@findex COMMAND_OBSCURE
+@findex gdb.COMMAND_OBSCURE
+@item COMMAND_OBSCURE
+The command is only used in unusual circumstances, or is not of
+general interest to users.  For example, @code{checkpoint},
+@code{fork}, and @code{stop} are in this category.  Type @code{help
+obscure} at the @value{GDBN} prompt to see a list of commands in this
+category.
+
+@findex COMMAND_MAINTENANCE
+@findex gdb.COMMAND_MAINTENANCE
+@item COMMAND_MAINTENANCE
+The command is only useful to @value{GDBN} maintainers.  The
+@code{maintenance} and @code{flushregs} commands are in this category.
+Type @code{help internals} at the @value{GDBN} prompt to see a list of
+commands in this category.
+@end table
+
+
+A new command can use a predefined completion function, either by
+specifying it via an argument at initialization, or by returning it
+from the @code{complete} method.  These predefined completion
+constants are all defined in the @code{gdb} module:
+
+@table @code
+@findex COMPLETE_NONE
+@findex gdb.COMPLETE_NONE
+@item COMPLETE_NONE
+This constant means that no completion should be done.
+
+@findex COMPLETE_FILENAME
+@findex gdb.COMPLETE_FILENAME
+@item COMPLETE_FILENAME
+This constant means that filename completion should be performed.
+
+@findex COMPLETE_LOCATION
+@findex gdb.COMPLETE_LOCATION
+@item COMPLETE_LOCATION
+This constant means that location completion should be done.
+@xref{Specify Location}.
+
+@findex COMPLETE_COMMAND
+@findex gdb.COMPLETE_COMMAND
+@item COMPLETE_COMMAND
+This constant means that completion should examine @value{GDBN}
+command names.
+
+@findex COMPLETE_SYMBOL
+@findex gdb.COMPLETE_SYMBOL
+@item COMPLETE_SYMBOL
+This constant means that completion should be done using symbol names
+as the source.
+@end table
+
+The following code snippet shows how a trivial CLI command can be
+implemented in Python:
+
+@smallexample
+class HelloWorld (gdb.Command):
+  """Greet the whole world."""
+
+  def __init__ (self):
+    super (HelloWorld, self).__init__ ("hello-world", gdb.COMMAND_OBSCURE)
+
+  def invoke (self, arg, from_tty):
+    print "Hello, World!"
+
+HelloWorld ()
+@end smallexample
+
+The last line instantiates the class, and is necessary to trigger the
+registration of the command with @value{GDBN}.  Depending on how the
+Python code is read into @value{GDBN}, you may need to import the
+@code{gdb} module explicitly.
+
 @node Interpreters
 @chapter Command Interpreters
 @cindex command interpreters
 @node Interpreters
 @chapter Command Interpreters
 @cindex command interpreters
index 6814a72..da05ee2 100644 (file)
@@ -71,7 +71,8 @@ struct interp
 
 /* Functions local to this file. */
 static void initialize_interps (void);
 
 /* Functions local to this file. */
 static void initialize_interps (void);
-static char **interpreter_completer (char *text, char *word);
+static char **interpreter_completer (struct cmd_list_element *cmd,
+                                    char *text, char *word);
 
 /* The magic initialization routine for this module. */
 
 
 /* The magic initialization routine for this module. */
 
@@ -416,7 +417,7 @@ interpreter_exec_cmd (char *args, int from_tty)
 
 /* List the possible interpreters which could complete the given text. */
 static char **
 
 /* List the possible interpreters which could complete the given text. */
 static char **
-interpreter_completer (char *text, char *word)
+interpreter_completer (struct cmd_list_element *ignore, char *text, char *word)
 {
   int alloced = 0;
   int textlen;
 {
   int alloced = 0;
   int textlen;
diff --git a/gdb/python/python-cmd.c b/gdb/python/python-cmd.c
new file mode 100644 (file)
index 0000000..36cde34
--- /dev/null
@@ -0,0 +1,585 @@
+/* gdb commands implemented in Python
+
+   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+
+#include "defs.h"
+#include "value.h"
+#include "exceptions.h"
+#include "python-internal.h"
+#include "charset.h"
+#include "gdbcmd.h"
+#include "cli/cli-decode.h"
+#include "completer.h"
+
+/* Struct representing built-in completion types.  */
+struct cmdpy_completer
+{
+  /* Python symbol name.  */
+  char *name;
+  /* Completion function.  */
+  char **(*completer) (struct cmd_list_element *, char *, char *);
+};
+
+static struct cmdpy_completer completers[] =
+{
+  { "COMPLETE_NONE", noop_completer },
+  { "COMPLETE_FILENAME", filename_completer },
+  { "COMPLETE_LOCATION", location_completer },
+  { "COMPLETE_COMMAND", command_completer },
+  { "COMPLETE_SYMBOL", make_symbol_completion_list_fn },
+};
+
+#define N_COMPLETERS (sizeof (completers) / sizeof (completers[0]))
+
+/* A gdb command.  For the time being only ordinary commands (not
+   set/show commands) are allowed.  */
+struct cmdpy_object
+{
+  PyObject_HEAD
+
+  /* The corresponding gdb command object, or NULL if the command is
+     no longer installed.  */
+  struct cmd_list_element *command;
+
+  /* A prefix command requires storage for a list of its sub-commands.
+     A pointer to this is passed to add_prefix_command, and to add_cmd
+     for sub-commands of that prefix.  If this Command is not a prefix
+     command, then this field is unused.  */
+  struct cmd_list_element *sub_list;
+};
+
+typedef struct cmdpy_object cmdpy_object;
+
+static PyTypeObject cmdpy_object_type;
+
+
+/* Constants used by this module.  */
+static PyObject *invoke_cst;
+static PyObject *complete_cst;
+
+\f
+
+/* Python function which wraps dont_repeat.  */
+static PyObject *
+cmdpy_dont_repeat (PyObject *self, PyObject *args)
+{
+  dont_repeat ();
+  Py_RETURN_NONE;
+}
+
+\f
+
+/* Called if the gdb cmd_list_element is destroyed.  */
+static void
+cmdpy_destroyer (struct cmd_list_element *self, void *context)
+{
+  cmdpy_object *cmd;
+  PyGILState_STATE state;
+
+  state = PyGILState_Ensure ();
+
+  /* Release our hold on the command object.  */
+  cmd = (cmdpy_object *) context;
+  cmd->command = NULL;
+  Py_DECREF (cmd);
+
+  /* We allocated the name, doc string, and perhaps the prefix
+     name.  */
+  xfree (self->name);
+  xfree (self->doc);
+  xfree (self->prefixname);
+
+  PyGILState_Release (state);
+}
+
+/* Called by gdb to invoke the command.  */
+static void
+cmdpy_function (struct cmd_list_element *command, char *args, int from_tty)
+{
+  cmdpy_object *obj = (cmdpy_object *) get_cmd_context (command);
+  PyObject *argobj, *ttyobj, *result;
+  struct cleanup *cleanup;
+  PyGILState_STATE state;
+
+  state = PyGILState_Ensure ();
+  cleanup = make_cleanup_py_restore_gil (&state);
+
+  if (! obj)
+    error (_("Invalid invocation of Python command object."));
+  if (! PyObject_HasAttr ((PyObject *) obj, invoke_cst))
+    {
+      if (obj->command->prefixname)
+       {
+         /* A prefix command does not need an invoke method.  */
+         do_cleanups (cleanup);
+         return;
+       }
+      error (_("Python command object missing 'invoke' method."));
+    }
+
+  if (! args)
+    args = "";
+  argobj = PyUnicode_Decode (args, strlen (args), host_charset (), NULL);
+  if (! argobj)
+    error (_("Could not convert arguments to Python string."));
+
+  ttyobj = from_tty ? Py_True : Py_False;
+  Py_INCREF (ttyobj);
+  result = PyObject_CallMethodObjArgs ((PyObject *) obj, invoke_cst, argobj,
+                                      ttyobj, NULL);
+  Py_DECREF (argobj);
+  Py_DECREF (ttyobj);
+  if (! result)
+    {
+      PyObject *ptype, *pvalue, *ptraceback;
+      char *s, *str;
+
+      PyErr_Fetch (&ptype, &pvalue, &ptraceback);
+
+      if (pvalue && PyString_Check (pvalue))
+       {
+         /* Make a temporary copy of the string data.  */
+         char *s = PyString_AsString (pvalue);
+         char *copy = alloca (strlen (s) + 1);
+         strcpy (copy, s);
+
+         PyErr_Restore (ptype, pvalue, ptraceback);
+         gdbpy_print_stack ();
+         error (_("Error occurred in Python command: %s"), copy);
+       }
+      else
+       {
+         PyErr_Restore (ptype, pvalue, ptraceback);
+         gdbpy_print_stack ();
+         error (_("Error occurred in Python command."));
+       }
+    }
+  Py_DECREF (result);
+  do_cleanups (cleanup);
+}
+
+/* Called by gdb for command completion.  */
+static char **
+cmdpy_completer (struct cmd_list_element *command, char *text, char *word)
+{
+  cmdpy_object *obj = (cmdpy_object *) get_cmd_context (command);
+  PyObject *textobj, *wordobj, *resultobj = NULL;
+  char **result = NULL;
+  struct cleanup *cleanup;
+  PyGILState_STATE state;
+
+  state = PyGILState_Ensure ();
+  cleanup = make_cleanup_py_restore_gil (&state);
+
+  if (! obj)
+    error (_("Invalid invocation of Python command object."));
+  if (! PyObject_HasAttr ((PyObject *) obj, complete_cst))
+    {
+      /* If there is no complete method, don't error -- instead, just
+        say that there are no completions.  */
+      goto done;
+    }
+
+  textobj = PyUnicode_Decode (text, strlen (text), host_charset (), NULL);
+  if (! textobj)
+    error (_("Could not convert argument to Python string."));
+  wordobj = PyUnicode_Decode (word, strlen (word), host_charset (), NULL);
+  if (! wordobj)
+    error (_("Could not convert argument to Python string."));
+
+  resultobj = PyObject_CallMethodObjArgs ((PyObject *) obj, complete_cst,
+                                         textobj, wordobj, NULL);
+  Py_DECREF (textobj);
+  Py_DECREF (wordobj);
+  if (! resultobj)
+    {
+      /* Just swallow errors here.  */
+      PyErr_Clear ();
+      goto done;
+    }
+  make_cleanup_py_decref (resultobj);
+
+  result = NULL;
+  if (PySequence_Check (resultobj))
+    {
+      Py_ssize_t i, len = PySequence_Size (resultobj);
+      Py_ssize_t out;
+      if (len < 0)
+       goto done;
+
+      result = (char **) xmalloc ((len + 1) * sizeof (char *));
+      for (i = out = 0; i < len; ++i)
+       {
+         int l;
+         PyObject *elt = PySequence_GetItem (resultobj, i);
+         if (elt == NULL || ! gdbpy_is_string (elt))
+           {
+             /* Skip problem elements.  */
+             PyErr_Clear ();
+             continue;
+           }
+         result[out] = python_string_to_host_string (elt);
+         ++out;
+       }
+      result[out] = NULL;
+    }
+  else if (PyInt_Check (resultobj))
+    {
+      /* User code may also return one of the completion constants,
+        thus requesting that sort of completion.  */
+      long value = PyInt_AsLong (resultobj);
+      if (value >= 0 && value < (long) N_COMPLETERS)
+       result = completers[value].completer (command, text, word);
+    }
+
+ done:
+
+  do_cleanups (cleanup);
+
+  return result;
+}
+
+/* Helper for cmdpy_init which locates the command list to use and
+   pulls out the command name.
+   
+   TEXT is the command name list.  The final word in the list is the
+   name of the new command.  All earlier words must be existing prefix
+   commands.
+
+   *BASE_LIST is set to the final prefix command's list of
+   *sub-commands.
+   
+   This function returns the xmalloc()d name of the new command.  On
+   error sets the Python error and returns NULL.  */
+static char *
+parse_command_name (char *text, struct cmd_list_element ***base_list)
+{
+  struct cmd_list_element *elt;
+  int len = strlen (text);
+  int i, lastchar;
+  char *prefix_text;
+  char *result;
+
+  /* Skip trailing whitespace.  */
+  for (i = len - 1; i >= 0 && (text[i] == ' ' || text[i] == '\t'); --i)
+    ;
+  if (i < 0)
+    {
+      PyErr_SetString (PyExc_RuntimeError, _("no command name found"));
+      return NULL;
+    }
+  lastchar = i;
+
+  /* Find first character of the final word.  */
+  for (; i > 0 && (isalnum (text[i - 1])
+                  || text[i - 1] == '-'
+                  || text[i - 1] == '_');
+       --i)
+    ;
+  result = xmalloc (lastchar - i + 2);
+  memcpy (result, &text[i], lastchar - i + 1);
+  result[lastchar - i + 1] = '\0';
+
+  /* Skip whitespace again.  */
+  for (--i; i >= 0 && (text[i] == ' ' || text[i] == '\t'); --i)
+    ;
+  if (i < 0)
+    {
+      *base_list = &cmdlist;
+      return result;
+    }
+
+  prefix_text = xmalloc (i + 2);
+  memcpy (prefix_text, text, i + 1);
+  prefix_text[i + 1] = '\0';
+
+  text = prefix_text;
+  elt = lookup_cmd_1 (&text, cmdlist, NULL, 1);
+  if (!elt || elt == (struct cmd_list_element *) -1)
+    {
+      PyErr_Format (PyExc_RuntimeError, _("could not find command prefix %s"),
+                   prefix_text);
+      xfree (prefix_text);
+      xfree (result);
+      return NULL;
+    }
+
+  if (elt->prefixlist)
+    {
+      xfree (prefix_text);
+      *base_list = elt->prefixlist;
+      return result;
+    }
+
+  PyErr_Format (PyExc_RuntimeError, _("'%s' is not a prefix command"),
+               prefix_text);
+  xfree (prefix_text);
+  xfree (result);
+  return NULL;
+}
+
+/* Object initializer; sets up gdb-side structures for command.
+
+   Use: __init__(NAME, CMDCLASS, [COMPLETERCLASS, [PREFIX]]).
+
+   NAME is the name of the command.  It may consist of multiple words,
+   in which case the final word is the name of the new command, and
+   earlier words must be prefix commands.
+
+   CMDCLASS is the kind of command.  It should be one of the COMMAND_*
+   constants defined in the gdb module.
+
+   COMPLETERCLASS is the kind of completer.  If not given, the
+   "complete" method will be used.  Otherwise, it should be one of the
+   COMPLETE_* constants defined in the gdb module.
+
+   If PREFIX is True, then this command is a prefix command.
+
+   The documentation for the command is taken from the doc string for
+   the python class.
+   
+*/
+static int
+cmdpy_init (PyObject *self, PyObject *args, PyObject *kwds)
+{
+  cmdpy_object *obj = (cmdpy_object *) self;
+  char *name;
+  int cmdtype;
+  int completetype = -1;
+  char *docstring = NULL;
+  volatile struct gdb_exception except;
+  struct cmd_list_element **cmd_list;
+  char *cmd_name, *pfx_name;
+  PyObject *is_prefix = NULL;
+  int cmp;
+
+  if (obj->command)
+    {
+      /* Note: this is apparently not documented in Python.  We return
+        0 for success, -1 for failure.  */
+      PyErr_Format (PyExc_RuntimeError,
+                   _("command object already initialized"));
+      return -1;
+    }
+
+  if (! PyArg_ParseTuple (args, "si|iO", &name, &cmdtype,
+                         &completetype, &is_prefix))
+    return -1;
+
+  if (cmdtype != no_class && cmdtype != class_run
+      && cmdtype != class_vars && cmdtype != class_stack
+      && cmdtype != class_files && cmdtype != class_support
+      && cmdtype != class_info && cmdtype != class_breakpoint
+      && cmdtype != class_trace && cmdtype != class_obscure
+      && cmdtype != class_maintenance)
+    {
+      PyErr_Format (PyExc_RuntimeError, _("invalid command class argument"));
+      return -1;
+    }
+
+  if (completetype < -1 || completetype >= (int) N_COMPLETERS)
+    {
+      PyErr_Format (PyExc_RuntimeError, _("invalid completion type argument"));
+      return -1;
+    }
+
+  cmd_name = parse_command_name (name, &cmd_list);
+  if (! cmd_name)
+    return -1;
+
+  pfx_name = NULL;
+  if (is_prefix != NULL) 
+    {
+      cmp = PyObject_IsTrue (is_prefix);
+      if (cmp == 1)
+       {
+         int i, out;
+         
+         /* Make a normalized form of the command name.  */
+         pfx_name = xmalloc (strlen (name) + 2);
+         
+         i = 0;
+         out = 0;
+         while (name[i])
+           {
+             /* Skip whitespace.  */
+             while (name[i] == ' ' || name[i] == '\t')
+               ++i;
+             /* Copy non-whitespace characters.  */
+             while (name[i] && name[i] != ' ' && name[i] != '\t')
+               pfx_name[out++] = name[i++];
+             /* Add a single space after each word -- including the final
+                word.  */
+             pfx_name[out++] = ' ';
+           }
+         pfx_name[out] = '\0';
+       }
+      else if (cmp < 0)
+         return -1;
+    }
+  if (PyObject_HasAttr (self, gdbpy_doc_cst))
+    {
+      PyObject *ds_obj = PyObject_GetAttr (self, gdbpy_doc_cst);
+      if (ds_obj && gdbpy_is_string (ds_obj))
+       docstring = python_string_to_host_string (ds_obj);
+    }
+  if (! docstring)
+    docstring = xstrdup (_("This command is not documented."));
+
+  Py_INCREF (self);
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      struct cmd_list_element *cmd;
+
+      if (pfx_name)
+       {
+         int allow_unknown;
+
+         /* If we have our own "invoke" method, then allow unknown
+            sub-commands.  */
+         allow_unknown = PyObject_HasAttr (self, invoke_cst);
+         cmd = add_prefix_cmd (cmd_name, (enum command_class) cmdtype,
+                               NULL, docstring, &obj->sub_list,
+                               pfx_name, allow_unknown, cmd_list);
+       }
+      else
+       cmd = add_cmd (cmd_name, (enum command_class) cmdtype, NULL,
+                      docstring, cmd_list);
+
+      /* There appears to be no API to set this.  */
+      cmd->func = cmdpy_function;
+      cmd->destroyer = cmdpy_destroyer;
+
+      obj->command = cmd;
+      set_cmd_context (cmd, self);
+      set_cmd_completer (cmd, ((completetype == -1) ? cmdpy_completer
+                              : completers[completetype].completer));
+    }
+  if (except.reason < 0)
+    {
+      xfree (cmd_name);
+      xfree (docstring);
+      xfree (pfx_name);
+      Py_DECREF (self);
+      PyErr_Format (except.reason == RETURN_QUIT
+                   ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
+                   "%s", except.message);
+      return -1;
+    }
+  return 0;
+}
+
+\f
+
+/* Initialize the 'commands' code.  */
+void
+gdbpy_initialize_commands (void)
+{
+  int i;
+
+  if (PyType_Ready (&cmdpy_object_type) < 0)
+    return;
+
+  /* Note: alias and user are special; pseudo appears to be unused,
+     and there is no reason to expose tui or xdb, I think.  */
+  if (PyModule_AddIntConstant (gdb_module, "COMMAND_NONE", no_class) < 0
+      || PyModule_AddIntConstant (gdb_module, "COMMAND_RUNNING", class_run) < 0
+      || PyModule_AddIntConstant (gdb_module, "COMMAND_DATA", class_vars) < 0
+      || PyModule_AddIntConstant (gdb_module, "COMMAND_STACK", class_stack) < 0
+      || PyModule_AddIntConstant (gdb_module, "COMMAND_FILES", class_files) < 0
+      || PyModule_AddIntConstant (gdb_module, "COMMAND_SUPPORT",
+                                 class_support) < 0
+      || PyModule_AddIntConstant (gdb_module, "COMMAND_STATUS", class_info) < 0
+      || PyModule_AddIntConstant (gdb_module, "COMMAND_BREAKPOINTS",
+                                 class_breakpoint) < 0
+      || PyModule_AddIntConstant (gdb_module, "COMMAND_TRACEPOINTS",
+                                 class_trace) < 0
+      || PyModule_AddIntConstant (gdb_module, "COMMAND_OBSCURE",
+                                 class_obscure) < 0
+      || PyModule_AddIntConstant (gdb_module, "COMMAND_MAINTENANCE",
+                                 class_maintenance) < 0)
+    return;
+
+  for (i = 0; i < N_COMPLETERS; ++i)
+    {
+      if (PyModule_AddIntConstant (gdb_module, completers[i].name, i) < 0)
+       return;
+    }
+
+  Py_INCREF (&cmdpy_object_type);
+  PyModule_AddObject (gdb_module, "Command",
+                     (PyObject *) &cmdpy_object_type);
+
+  invoke_cst = PyString_FromString ("invoke");
+  complete_cst = PyString_FromString ("complete");
+}
+
+\f
+
+static PyMethodDef cmdpy_object_methods[] =
+{
+  { "dont_repeat", cmdpy_dont_repeat, METH_NOARGS,
+    "Prevent command repetition when user enters empty line." },
+
+  { 0 }
+};
+
+static PyTypeObject cmdpy_object_type =
+{
+  PyObject_HEAD_INIT (NULL)
+  0,                             /*ob_size*/
+  "gdb.Command",                 /*tp_name*/
+  sizeof (cmdpy_object),         /*tp_basicsize*/
+  0,                             /*tp_itemsize*/
+  0,                             /*tp_dealloc*/
+  0,                             /*tp_print*/
+  0,                             /*tp_getattr*/
+  0,                             /*tp_setattr*/
+  0,                             /*tp_compare*/
+  0,                             /*tp_repr*/
+  0,                             /*tp_as_number*/
+  0,                             /*tp_as_sequence*/
+  0,                             /*tp_as_mapping*/
+  0,                             /*tp_hash */
+  0,                             /*tp_call*/
+  0,                             /*tp_str*/
+  0,                             /*tp_getattro*/
+  0,                             /*tp_setattro*/
+  0,                             /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+  "GDB command object",                  /* tp_doc */
+  0,                             /* tp_traverse */
+  0,                             /* tp_clear */
+  0,                             /* tp_richcompare */
+  0,                             /* tp_weaklistoffset */
+  0,                             /* tp_iter */
+  0,                             /* tp_iternext */
+  cmdpy_object_methods,                  /* tp_methods */
+  0,                             /* tp_members */
+  0,                             /* tp_getset */
+  0,                             /* tp_base */
+  0,                             /* tp_dict */
+  0,                             /* tp_descr_get */
+  0,                             /* tp_descr_set */
+  0,                             /* tp_dictoffset */
+  cmdpy_init,                    /* tp_init */
+  0,                             /* tp_alloc */
+  PyType_GenericNew              /* tp_new */
+};
index 1457928..02dbfc4 100644 (file)
@@ -70,6 +70,7 @@ PyObject *value_to_value_object (struct value *v);
 struct value *convert_value_from_python (PyObject *obj);
 
 void gdbpy_initialize_values (void);
 struct value *convert_value_from_python (PyObject *obj);
 
 void gdbpy_initialize_values (void);
+void gdbpy_initialize_commands (void);
 
 struct cleanup *make_cleanup_py_decref (PyObject *py);
 struct cleanup *make_cleanup_py_restore_gil (PyGILState_STATE *state);
 
 struct cleanup *make_cleanup_py_decref (PyObject *py);
 struct cleanup *make_cleanup_py_restore_gil (PyGILState_STATE *state);
@@ -94,4 +95,6 @@ char *python_string_to_host_string (PyObject *obj);
 PyObject *target_string_to_unicode (const gdb_byte *str, int length);
 int gdbpy_is_string (PyObject *obj);
 
 PyObject *target_string_to_unicode (const gdb_byte *str, int length);
 int gdbpy_is_string (PyObject *obj);
 
+extern PyObject *gdbpy_doc_cst;
+
 #endif /* GDB_PYTHON_INTERNAL_H */
 #endif /* GDB_PYTHON_INTERNAL_H */
index 96bb5f5..4f97416 100644 (file)
@@ -46,6 +46,8 @@ static PyMethodDef GdbMethods[];
 
 PyObject *gdb_module;
 
 
 PyObject *gdb_module;
 
+PyObject *gdbpy_doc_cst;
+
 /* Given a command_line, return a command string suitable for passing
    to Python.  Lines in the string are separated by newlines.  The
    return value is allocated using xmalloc and the caller is
 /* Given a command_line, return a command string suitable for passing
    to Python.  Lines in the string are separated by newlines.  The
    return value is allocated using xmalloc and the caller is
@@ -407,9 +409,12 @@ Enables or disables printing of Python stack traces."),
   PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG", (char*) target_name);
 
   gdbpy_initialize_values ();
   PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG", (char*) target_name);
 
   gdbpy_initialize_values ();
+  gdbpy_initialize_commands ();
 
   PyRun_SimpleString ("import gdb");
 
 
   PyRun_SimpleString ("import gdb");
 
+  gdbpy_doc_cst = PyString_FromString ("__doc__");
+
   /* Create a couple objects which are used for Python's stdout and
      stderr.  */
   PyRun_SimpleString ("\
   /* Create a couple objects which are used for Python's stdout and
      stderr.  */
   PyRun_SimpleString ("\
index b9befed..97d7950 100644 (file)
@@ -3890,6 +3890,16 @@ make_symbol_completion_list (char *text, char *word)
   return current_language->la_make_symbol_completion_list (text, word);
 }
 
   return current_language->la_make_symbol_completion_list (text, word);
 }
 
+/* Like make_symbol_completion_list, but suitable for use as a
+   completion function.  */
+
+char **
+make_symbol_completion_list_fn (struct cmd_list_element *ignore,
+                               char *text, char *word)
+{
+  return make_symbol_completion_list (text, word);
+}
+
 /* Like make_symbol_completion_list, but returns a list of symbols
    defined in a source file FILE.  */
 
 /* Like make_symbol_completion_list, but returns a list of symbols
    defined in a source file FILE.  */
 
index 2446d1e..8b086f3 100644 (file)
@@ -1238,6 +1238,8 @@ extern void select_source_symtab (struct symtab *);
 
 extern char **default_make_symbol_completion_list (char *, char *);
 extern char **make_symbol_completion_list (char *, char *);
 
 extern char **default_make_symbol_completion_list (char *, char *);
 extern char **make_symbol_completion_list (char *, char *);
+extern char **make_symbol_completion_list_fn (struct cmd_list_element *,
+                                             char *, char *);
 
 extern char **make_file_symbol_completion_list (char *, char *, char *);
 
 
 extern char **make_file_symbol_completion_list (char *, char *, char *);
 
index b77ea99..0b72438 100644 (file)
@@ -1,3 +1,7 @@
+2009-02-06  Thiago Jung Bauermann  <bauerman@br.ibm.com>
+
+       * gdb.python/python-cmd.exp: New file.
+
 2009-02-06  Tristan Gingold  <gingold@adacore.com>
 
        * gdb.arch/i386-sse.c (main): Replace call to puts by an nop asm.
 2009-02-06  Tristan Gingold  <gingold@adacore.com>
 
        * gdb.arch/i386-sse.c (main): Replace call to puts by an nop asm.