Added the apropos command
authorDaniel Berlin <dberlin@dberlin.org>
Thu, 23 Mar 2000 23:21:27 +0000 (23:21 +0000)
committerDaniel Berlin <dberlin@dberlin.org>
Thu, 23 Mar 2000 23:21:27 +0000 (23:21 +0000)
gdb/ChangeLog
gdb/command.c
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/help.exp

index 132e12b3478a3b02c69663f40268e0bf1f1fde36..8d5b70e565be95b96a8de506e5f111edb294ef59 100644 (file)
        (delete_file_handler, handle_file_event): Likewise.
        (gdb_wait_for_event, poll_timers): Likewise.
 
+2000-03-22  Daniel Berlin  <dan@cgsoftware.com>
+       * command.c (apropos_cmd_helper): New function, meat of the
+       apropos command.
+       (apropos_command): New apropos command to search command
+       names/documentation for regular expressions.
+       (_initialize_command): Add the apropos command.
+
 2000-03-22  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>
 
        * printcmd.c (print_scalar_formatted):  Truncate addresses to the
index e0b7ad79fd1b6f25a2a17d7baa7f276cb40ef5cd..826cc46dfceb717fdff02f89cbaa8c84bcbd5079 100644 (file)
@@ -27,7 +27,7 @@
 #endif
 
 #include "gdb_wait.h"
-
+#include "gnu-regex.h"
 /* FIXME: this should be auto-configured!  */
 #ifdef __MSDOS__
 # define CANT_FORK
@@ -54,6 +54,10 @@ static struct cmd_list_element *find_cmd PARAMS ((char *command,
                                            struct cmd_list_element * clist,
                                                  int ignore_help_classes,
                                                  int *nfound));
+static void apropos_cmd_helper (struct ui_file *, struct cmd_list_element *, 
+                               struct re_pattern_buffer *, char *);
+
+void apropos_command (char *, int);
 
 void _initialize_command PARAMS ((void));
 
@@ -370,6 +374,87 @@ delete_cmd (name, list)
          c = c->next;
       }
 }
+/* Recursively walk the commandlist structures, and print out the
+   documentation of commands that match our regex in either their
+   name, or their documentation.
+*/
+static void 
+apropos_cmd_helper (struct ui_file *stream, struct cmd_list_element *commandlist,
+                        struct re_pattern_buffer *regex, char *prefix)
+{
+  register struct cmd_list_element *c;
+  int returnvalue=1; /*Needed to avoid double printing*/
+  /* Walk through the commands */
+  for (c=commandlist;c;c=c->next)
+    {
+      if (c->name != NULL)
+       {
+         /* Try to match against the name*/
+         returnvalue=re_search(regex,c->name,strlen(c->name),0,strlen(c->name),NULL);
+         if (returnvalue >= 0)
+           {
+             /* Stolen from help_cmd_list. We don't directly use
+              * help_cmd_list because it doesn't let us print out
+              * single commands
+              */
+             fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
+             print_doc_line (stream, c->doc);
+             fputs_filtered ("\n", stream);
+             returnvalue=0; /*Set this so we don't print it again.*/
+           }
+       }
+      if (c->doc != NULL && returnvalue != 0)
+       {
+         /* Try to match against documentation */
+         if (re_search(regex,c->doc,strlen(c->doc),0,strlen(c->doc),NULL) >=0)
+           {
+             /* Stolen from help_cmd_list. We don't directly use
+              * help_cmd_list because it doesn't let us print out
+              * single commands
+              */
+             fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
+             print_doc_line (stream, c->doc);
+             fputs_filtered ("\n", stream);
+           }
+       }
+      /* Check if this command has subcommands */
+      if (c->prefixlist != NULL)
+       {
+         /* Recursively call ourselves on the subcommand list,
+            passing the right prefix in.
+         */
+         apropos_cmd_helper(stream,*c->prefixlist,regex,c->prefixname);
+       }
+    }
+}
+/* Search through names of commands and documentations for a certain
+   regular expression.
+*/
+void 
+apropos_command (char *searchstr, int from_tty)
+{
+  extern struct cmd_list_element *cmdlist; /*This is the main command list*/
+  regex_t pattern;
+  char *pattern_fastmap;
+  char errorbuffer[512];
+  pattern_fastmap=calloc(256,sizeof(char));
+  if (searchstr == NULL)
+      error("REGEXP string is empty");
+
+  if (regcomp(&pattern,searchstr,REG_ICASE) == 0)
+    {
+      pattern.fastmap=pattern_fastmap;
+      re_compile_fastmap(&pattern);
+      apropos_cmd_helper(gdb_stdout,cmdlist,&pattern,"");
+    }
+  else
+    {
+      regerror(regcomp(&pattern,searchstr,REG_ICASE),NULL,errorbuffer,512);
+      error("Error in regular expression:%s",errorbuffer);
+    }
+  free(pattern_fastmap);
+}
+
 
 /* This command really has to deal with two things:
  *     1) I want documentation on *this string* (usually called by
@@ -1693,4 +1778,5 @@ With no arguments, run an inferior shell.");
           "Show definitions of user defined commands.\n\
 Argument is the name of the user defined command.\n\
 With no argument, show definitions of all user defined commands.", &showlist);
+  add_com ("apropos", class_support, apropos_command, "Search for commands matching a REGEXP");
 }
index b0f2654e94b4026a081303de837a76a97df952d4..48efadf2bbecb86e75351b02a34b35c598c06d48 100644 (file)
@@ -1,3 +1,7 @@
+2000-03-22  Daniel Berlin  <dan@cgsoftware.com>
+
+      * gdb.texinfo: Add documentation for the apropos command.
+
 2000-03-20  Michael Snyder  <msnyder@cleaver.cygnus.com>
 
        * gdb.texinfo: Add white space to prevent overprinting in 
index 15a0820ce95d21a7554f4837aa2cd8f5f8ac3d68..7ccfe03e46f2a4526c12287655b1b6cc8c172fd2 100644 (file)
@@ -1318,6 +1318,25 @@ Command name abbreviations are allowed if unambiguous.
 With a command name as @code{help} argument, @value{GDBN} displays a
 short paragraph on how to use that command.
 
+@kindex apropos
+@item apropos @var{args}
+The @code{apropos @var{args}} command searches through all of the @value{GDBN}
+commands, and their documentation, for the regular expression specified in
+@var{args}. It prints out all matches found. For example:
+
+@smallexample
+apropos reload
+@end smallexample
+
+@noindent results in:
+
+@smallexample
+@group
+set symbol-reloading -- Set dynamic symbol table reloading multiple times in one run
+show symbol-reloading -- Show dynamic symbol table reloading multiple times in one run
+@end group
+@end smallexample
+
 @kindex complete
 @item complete @var{args}
 The @code{complete @var{args}} command lists all the possible completions
index 47bc29f324898b6c0647675683d7fbeb91a84100..ded1f39d9bc4847cd8dce26aeeb8c06bd14c10a3 100644 (file)
@@ -1,3 +1,7 @@
+2000-03-22  Daniel Berlin   <dan@cgsoftware.com>
+
+       * gdb.base/help.exp: Added test for new apropos command.
+
 2000-03-21  Kevin Buettner <kevinb@redhat.com>
 
        * gdb.base/pointers.c (usevar): New function.
index c78bd893899fc4345cd73a9870663d10dfe34422..9515132daed39719ea994292a83dfffa10997bd2 100644 (file)
@@ -540,3 +540,9 @@ gdb_test "help x" "Examine memory: x/FMT ADDRESS..*\[\r\n\]+ADDRESS is an expres
 gdb_test "help info bogus-gdb-command" "Undefined info command: \"bogus-gdb-command\".  Try \"help info\"."  "help info bogus-gdb-command"
 # test help gotcha
 gdb_test "help gotcha" "Undefined command: \"gotcha\".  Try \"help\"."  "help gotcha"
+# test apropos regex
+gdb_test "apropos \\\(print\[\^ bsiedf\\\".\]\\\)" "handle -- Specify how to handle a signal"
+# test apropos >1 word string
+gdb_test "apropos handle a signal" "handle -- Specify how to handle a signal"
+# test apropos apropos
+gdb_test "apropos apropos" "apropos -- Search for commands matching a REGEXP"